Created attachment 32521 [details] wmaybe_uninitialized_strange_behavior.c Given this code: enum A { A1, A2 }; enum B { B1 }; static inline int fa (enum A a) { int n; switch (a) { case A1: n = 1; break; case A2: n = 2; break; } return n; } static inline int fb (enum B b) { int n; switch (b) { case B1: n = 1; break; } return n; } int main (int argc, char **) { return fa((A)argc) + fb((B)argc); } $ g++ -O1 -Wall wmaybe_uninitialized_strange_behavior.c wmaybe_uninitialized_strange_behavior.c: In function ‘int main(int, char**)’: wmaybe_uninitialized_strange_behavior.c:27:36: warning: ‘n’ may be used uninitialized in this function [-Wmaybe-uninitialized] return fa((A)argc) + fb((B)argc); ^ 1) gcc generates warning for 'fa' function, but not for 'fb' function. 2) The message points to the end of expression, that contains 'fa' call (not to 'fa' declaration, or at least to 'fa' call). The message mentions name of a variable, that is used in 'fa' declaration. So we're lucky that the same name doesn't appear in the calling function (main). 3) This all happens with -O1 or higher, with -O0 there's no warnings at all!
We don't warn for fb(), because PR18501. So the only original bug here is the location when warning. The problem is the locations that are propagated when transforming expressions. We reach: # n_4 = PHI <n_5(D)(3), [test.cc : 6:17] 1(6), [test.cc : 7:17] 2(4)> <L3>: [test.cc : 20:32] # RANGE [-2147483648, 2147483647] NONZERO 0x00000000000000007 _2 = n_4 + 1; When instead we should have a location for n_4 that is different than the location for '+'. In any case, pointing to the closing parenthesis is very confusing. At worst it should point to the '+'.
(In reply to Manuel López-Ibáñez from comment #1) > We don't warn for fb(), because PR18501. > > So the only original bug here is the location when warning. The problem is > the locations that are propagated when transforming expressions. We reach: > > # n_4 = PHI <n_5(D)(3), [test.cc : 6:17] 1(6), [test.cc : 7:17] 2(4)> > <L3>: > [test.cc : 20:32] # RANGE [-2147483648, 2147483647] NONZERO > 0x00000000000000007 > _2 = n_4 + 1; > > When instead we should have a location for n_4 that is different than the > location for '+'. The location of n_4 depends on the edge you are coming from (thus n_4 itself doesn't have a location). The warning code picks the location of an actual use of n_4 in that case, here that of _2 = n_4 + 1; this points to the plus in main, but appearantly slightly wrong. At the point where we emit the warning we can't really do better, but we could at least also hint where 'n' was declared and/or inlined from. > In any case, pointing to the closing parenthesis is very confusing. At worst > it should point to the '+'.
Fix blocks/depends list.
The poor location in C++ is also tracked in pr81714. Let me keep that bug open since it has a simpler test case and resolve this one as its dupe. (The C front end does point to the + expression.) *** This bug has been marked as a duplicate of bug 81714 ***