https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78081
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |msebor at gcc dot gnu.org Known to fail|5.4.0, 6.3.0, 7.0.1, 8.0 |10.2.0, 11.0, 5.5.0, 6.4.0, | |7.2.0, 8.3.0, 9.1.0 --- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> --- Reconfirmed with GCC 11 and both the original test case as well as the reduced test case below. The warning is augmented to print a couple of notes, the first showing the condition under which the variable is determined to be uninitialized, and the second the condition under which it's used. The expressions printed in the notes: (s == 0) and (s != 0 && (f (s_23) != 1), are clearly mutually exclusive but the warning has recorded '(.NOT.) _1 == 1 (.AND.) s_23 != 0B' as the used condition and doesn't have the smarts to figure out that the s_23 PHI <s_3(5), 0B(10)> is equal to s_3(5) in bb 8. $ cat pr78081.c && gcc -O2 -S -Wall -fdump-tree-uninit=/dev/stdout pr78081.c extern int f (const char *); int g (const char *s0, const char *s1) { for (const char *s = s1; ; ) { long i; if (s) i = s - s0; if (f (s) == 1) break; if (s) s = i + s0; } return -1; } ;; Function g (g, funcdef_no=0, decl_uid=1946, cgraph_uid=1, symbol_order=0) ... Testing if this predicate: (.NOT.) s_3 != 0B <<< s != 0 ...can be invalidated by a USE guard of: (.NOT.) _1 == 1 (.AND.) s_23 != 0B <<< s != 0 [BEFORE SIMPLICATION -- [USE]: i.0_2 = (sizetype) i_22; is guarded by : (.NOT.) _1 == 1 (.AND.) s_23 != 0B [BEFORE NORMALIZATION --[USE]: i.0_2 = (sizetype) i_22; is guarded by : (.NOT.) _1 == 1 (.AND.) s_23 != 0B [AFTER NORMALIZATION -- [USE]: i.0_2 = (sizetype) i_22; is guarded by : s_23 != 0B (.AND.) (.NOT.) _1 == 1 [CHECK]: Found unguarded use: i.0_2 = (sizetype) i_22; pr78081.c: In function ‘g’: pr78081.c:16:15: warning: ‘i’ may be used uninitialized in this function [-Wmaybe-uninitialized] 16 | s = i + s0; | ~~^~~~ pr78081.c:7:12: note: when ‘s == 0’ 7 | long i; | ^ pr78081.c:7:12: note: used when ‘s != 0 && f (s_23) != 1’ pr78081.c:7:12: note: ‘i’ was declared here int g (const char * s0, const char * s1) { long int i; const char * s; int _1; sizetype i.0_2; <bb 2> [local count: 118111598]: <bb 3> [local count: 787052758]: # s_3 = PHI <s_13(8), s1_7(D)(2)> # i_4 = PHI <i_22(8), i_8(D)(2)> <<< i_8(D) is uninitialized if (s_3 != 0B) goto <bb 4>; [90.32%] else goto <bb 11>; [9.68%] <bb 11> [local count: 76166394]: goto <bb 5>; [100.00%] <bb 4> [local count: 751619280]: i_11 = s_3 - s0_10(D); <bb 5> [local count: 827785674]: <<< s_3 != 0 # i_22 = PHI <i_4(11), i_11(4)> <<< (2) <bb 6> [local count: 1073741824]: # s_23 = PHI <s_3(5), 0B(10)> <<< s_23 _1 = f (s_23); if (_1 == 1) goto <bb 9>; [11.00%] else goto <bb 7>; [89.00%] <bb 7> [local count: 955630225]: if (s_23 != 0B) <<< s_23 != 0 goto <bb 8>; [70.00%] else goto <bb 10>; [30.00%] <bb 10> [local count: 286689065]: goto <bb 6>; [100.00%] <bb 8> [local count: 668941161]: <<< s_23 != 0 i.0_2 = (sizetype) i_22; <<< (1) s_13 = s0_10(D) + i.0_2; <<< use: -Wmaybe-uninitialized goto <bb 3>; [100.00%] <bb 9> [local count: 118111600]: return -1; }