Summary: | gcc 4.9.1 doesn't warn about uninitialized variable use declared in a switch/case statement when compiled with -O | ||
---|---|---|---|
Product: | gcc | Reporter: | Joe Perches <joe> |
Component: | c | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED INVALID | ||
Severity: | normal | CC: | jakub |
Priority: | P3 | ||
Version: | 4.9.1 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2015-04-20 00:00:00 | |
Attachments: | sample code |
This is because at the point where we warn we don't know that the code is executed unconditionally and with optimization we don't warn about maybe-uninitialized uses early. Late we have removed all code as dead and thus do not warn either. I'd say it works as intended (even though surprising). This changed supposedly with r138933 and from that PR20644 I think it is quite clear this is intentional. The code in foo_2 is conditional (on a condition later proved to be always true, though), so we really don't want to warn on it early, because it might be in dead code, and we don't warn for it late because it really is dead code, optimized away as nothing uses it. If you add say a global void *b; variable and change the a = a; statements to b = a;, then it will warn even when optimizing, as the code won't be dead. Thank you both for your very prompt replies. It might be useful to have a -Wunused-eliminated type extra warning though that might be very noisy. So shouldn't this be INVALID rather than NEW? Sure. |
Created attachment 35365 [details] sample code Here is a small example: $ cat t.c struct foo { int bar[100]; }; void foo_1(void) { unsigned int m; extern struct foo *array[100]; struct foo *a = array[m]; a = a; } void foo_2(void) { int i = 1; switch (i) { case 1: { unsigned int m; extern struct foo *array[100]; struct foo *a = array[m]; a = a; break; } } } $ gcc warns properly about both foo_1 and foo_2 without -O $ gcc -c -Wall t.c t.c: In function ‘foo_1’: t.c:9:14: warning: ‘m’ is used uninitialized in this function [-Wuninitialized] struct foo *a = array[m]; ^ t.c: In function ‘foo_2’: t.c:21:15: warning: ‘m’ may be used uninitialized in this function [-Wmaybe-uninitialized] struct foo *a = array[m]; ^ $ but gcc warns about foo_1 but not foo_2 with -O $ gcc -c -Wall -O t.c t.c: In function ‘foo_1’: t.c:9:14: warning: ‘m’ is used uninitialized in this function [-Wuninitialized] struct foo *a = array[m]; ^ $ gcc -v Using built-in specs. COLLECT_GCC=/usr/bin/gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.9.1-16ubuntu6' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.9.1 (Ubuntu 4.9.1-16ubuntu6)