Created attachment 41387 [details] test case Hi. I'm using gcc 7.1.0 from Debian/experimental (Debian package gcc-7 version 7.1.0-5). I ran into a case where an uninitialized variable could be returned from a function without triggering a warning. With the attached minimized source tst.c the following does not yield a warning: gcc-7 -DCALL -DTEST2 -Wall -Wextra -o /dev/null -c tst.c Here I initialize some parts of the S structure (s.x), but not others (s.y). And I return the uninitialized piece: s.y. The extra f() call at the beginning of g() triggers the bug: taking that call out with gcc-7 -DTEST2 -Wall -Wextra -o /dev/null -c tst.c produces the warning as it should. Furthermore, initializing s.x in a slightly different way makes the bug go away as well: this produces the warning also: gcc-7 -DCALL -Wall -Wextra -o /dev/null -c tst.c Finally, it looks like gcc-6 had a similar issue where the extra call to f() makes the warning go away, but it was fixed in gcc-7: the following misses the warning: gcc-6 -DCALL -DTEST2 -Wall -Wextra -o /dev/null -c tst.c Maybe the fix to THIS bug would be similar. Thanks!
There might be another bug already for this one.
I just tried this with Debian builds of gcc8 and gcc9: 8.3.0-19 and 9.2.1-8. This bug still exists in both.
Confirmed with GCC 11 and the slightly smaller test case below. With -O0, the warning is issued in the first case because GCC sees the initialization modifies just the two array elements and not s.b. It's not issued in the second case because the warning relies on the optimizer infrastructure to tell it if s.b might be modified and because the optimizer doesn't run at -O0 the constant values aren't propagated into the array dereferences and so the infrastructure (exceedingly conservatively) assumes that the accesses to s.a might modify other members of s. This is a downside of warnings using the same conservative assumptions as optimizers must. To do better, the warning would have to avoid some of these conservative assumptions. This isn't really a bug but a limitation inherent in most of these warnings. $ cat z.c && gcc -S -Wall z.c void f (void); int g (void) { f (); struct S { int a[2], b; } s; enum { i = 0, j = 1 }; s.a[i] = 0; s.a[j] = 0; return s.b; // -Wuninitialized } int h (void) { f (); struct S { int a[2], b; } s; int i = 0, j = 1; s.a[i] = 0; s.a[j] = 0; return s.b; // missing warning } z.c: In function ‘g’: z.c:12:11: warning: ‘s.b’ is used uninitialized [-Wuninitialized] 12 | return s.b; // -Wuninitialized | ~^~ z.c:7:29: note: ‘s’ declared here 7 | struct S { int a[2], b; } s; | ^