Reduced test code: ``` int mem(char *data); int cond(void); void f(char *data, unsigned idx, unsigned inc) { char *d2; int c = cond(); if (idx >= 2) { if (c) d2 = data; mem(data); } else if (inc > 3) { if (c) d2 = data; mem(data); } else { if (c) { d2 = data; } } if (*data) { } else if (c) { mem(d2); } } ``` Compiling with `gcc -Wall -Wextra -O{1,2,s,3,fast}` warns about ``` a.c: In function 'f': a.c:27:9: warning: 'd2' may be used uninitialized in this function [-Wmaybe-uninitialized] 27 | mem(d2); | ^~~~~~~ ``` However, it should be clear that `d2` is always assigned when `c` is true. In fact, it seems that GCC could figure this out in some cases. Changes that can surpress the warning includes, 1. Remove any of the `mem(data)` calls. 2. Remove any one of the `if`s (leaving only the if or else branch unconditionally) 3. Change first condition to be on inc instead. 4. Removing the last `*data` branch. Version tested: AArch64: 10.2.0 ARM: 9.1.0 x86_64: 10.1.0 mingw64: 10.2.0
the control-flow analysis of the uninit warning isn't powerful enough to capture this.
Yes, the pass seems to give up: [CHECK]: Found unguarded use: d2_29 = PHI <d2_4(19), data_13(D)(22)> [WORKLIST]: Update worklist with phi: d2_29 = PHI <d2_4(19), data_13(D)(22)> [CHECK]: examining phi: d2_29 = PHI <d2_4(19), data_13(D)(22)> [CHECK]: Found unguarded use: mem (d2_29); [tail call]
Just curious, is it some particular structure that is upsetting it or did it simply hit some depth limit.
It's worth noting that at -O2, -O3 and -Ofast the warning does not trigger. I haven't dug deeply as this is fairly common. At higher optimization levels the various optimizers try harder to find and eliminate redundancies.