https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116449
Bug ID: 116449 Summary: Miscompilation with UBSAN Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: sirl at gcc dot gnu.org CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org, kcc at gcc dot gnu.org Target Milestone: --- Hi, compiling this example with g++-trunk -c -fsanitize=undefined test.cpp -O2 -W -Wall class C { public: void P(int); void IP(); int parr[16]; }; typedef void (C::*fp)(); typedef struct arr_t { fp func; } arr_t; static arr_t farr[1] = { { &C::IP }, }; void C::P(int c) { ((*this).*farr[parr[c]].func)(); } results in this warning test.cpp: In member function 'void C::P(int)': test.cpp:23:31: warning: '<anonymous>' may be used uninitialized [-Wmaybe-uninitialized] 23 | ((*this).*farr[parr[c]].func)(); | ~~~~~~~~~~~~^ But the real problem is miscompilation that starts already in the gimple dump: void C::P (struct C * const this, int c) { void C::<T40d> (struct C *) * iftmp.0; int D.3291; int D.3294; struct C * D.3296; D.3291 = this->parr[c]; .UBSAN_BOUNDS (0B, D.3291, 1); _1 = farr[D.3291].func.__pfn; _2 = (long int) _1; _3 = _2 & 1; if (_3 == 0) goto <D.3292>; else goto <D.3293>; <D.3292>: D.3294 = this->parr[c]; .UBSAN_BOUNDS (0B, D.3294, 1); iftmp.0 = farr[D.3294].func.__pfn; goto <D.3295>; <D.3293>: .UBSAN_BOUNDS (0B, D.3294, 1); _4 = farr[D.3294].func.__delta; _5 = (sizetype) _4; _6 = this + _5; _7 = MEM[(int (*) () * *)_6]; .UBSAN_BOUNDS (0B, D.3294, 1); _8 = farr[D.3294].func.__pfn; _9 = (long int) _8; _10 = _9 - 1; _11 = (sizetype) _10; _12 = _7 + _11; iftmp.0 = *_12; <D.3295>: iftmp.1_13 = iftmp.0; .UBSAN_BOUNDS (0B, D.3294, 1); _14 = farr[D.3294].func.__delta; _15 = (sizetype) _14; D.3296 = this + _15; .UBSAN_NULL (D.3296, 4B, 4); iftmp.1_13 (D.3296); } As you can see ".UBSAN_BOUNDS (0B, D.3294, 1)" check is repeated multiple times, but in the <D.3293> branch D.3294 is not initialized at all. This causes wrong out-of-bounds reports and eventually even application crashes (seen in the original testcase). Tested with trunk@r15-3043, but it seems all versions since at least GCC-10 are affected.