Compiler version - trunk @ 192770 Compilation option - -c -O2 -Wall Source - static void a(int *i) { } static void b(int p) { } int main(int argc, char *argv[]) { int i; a(&i); b(i); return 0; } Compilation output - /home/shenhan/test.c: In function ‘main’: /home/shenhan/test.c:7:4: warning: ‘i’ is used uninitialized in this function [-Wuninitialized] b(i); ^ A quick diagnose by David (Xingliang) Li is copied below - "The early uninitialized variable warning happens before inlining phase. Before 4.7, compiler does not warn this because the call to a(&i) which may initialize 'i' (the analysis is only intra-procedural). In 4.7 (and above), the SRA optimization pass which happens before the analysis is smart enough to replace the call to 'a' into a clone of 'a' which takes no argument. However the second access to 'i' still remains, thus the warning."
Is it only because b does not use its arguments you are saying it is a false un-initialized warning?
Yeah, I think value of "i" is never used.
This doesn't warn, so it seems there is something else going on apart from SRA. static void b(int p) { } int main(int argc, char *argv[]) { int i; b(i); return 0; } Moving a(&i) after b(i) also prevents the warning. Weird.
And the caret location is off-by-one. More weird.
At the point of the early uninit pass it sees: main (int argc, char * * argv) { int i; int D.1716; int i.0; <bb 2>: a.isra.0 (); # VUSE <.MEM_3(D)> i.0_1 = i; b.isra.1 (); D.1716_2 = 0; # .MEM_4 = VDEF <.MEM_3(D)> i ={v} {CLOBBER}; # VUSE <.MEM_4> return D.1716_2; thus a read from the memory location 'i' which is uninitialized. Dead code elimination has not yet removed that read (i.0_1 is unused after all). I'd say the literal presence of b (i) is considered a use of i in C-terms, thus the warning is not really incorrect. That IPA-SRA has this side-effect on the otherwise still unoptimized body of main is bad - early uninit was put before early inlining for a reason and now IPA-SRA defeats this ... can we make it more "IPA" like and have an explicit local transform stage?
This seems fixed in GCC 9, even with -O1, but a testcase should be added to the testsuite to prevent regression: /* {dg-options "-O1 -Wuninitialized" }*/ static void a(int *i) { } static void b(int p) { } int foo(void) { int i; a(&i); b(i); return 0; } static void c(int *i) { } extern void d(int p); int bar(void) { int i; c(&i); d(i); /* dg-warning "uninitialized" */ return 0; } extern void e(int *i); static void f(int p) {}; int baz(void) { int i; e(&i); f(i); return 0; }
Bisection points to r217125 as the fix. Let me add the test and resolve it.
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>: https://gcc.gnu.org/g:e88ca9f42306e291d3cb2d34dd7f2b017a3c1e52 commit r11-7841-ge88ca9f42306e291d3cb2d34dd7f2b017a3c1e52 Author: Martin Sebor <msebor@redhat.com> Date: Thu Mar 25 17:23:06 2021 -0600 PR tree-optimization/55060 - False un-initialized variable warnings gcc/testsuite/ChangeLog: PR tree-optimization/55060 * gcc.dg/uninit-pr55060.c: New.