Bug 45609

Summary: [4.3/4.4/4.5/4.6 Regression] 'is used uninitialized' becomes 'may be used uninitialized' on unrelated code changes (namespace addition)
Product: gcc Reporter: Andreas Beckmann <gcc>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED INVALID    
Severity: normal CC: gcc-bugs, manu
Priority: P3 Keywords: diagnostic
Version: 4.5.0   
Target Milestone: 4.3.6   
Host: Target:
Build: Known to work: 4.2.5
Known to fail: 4.3.6 4.4.5 4.5.2 4.6.0 Last reconfirmed: 2010-09-09 08:00:56
Bug Depends on:    
Bug Blocks: 24639    
Attachments: minimized testcase

Description Andreas Beckmann 2010-09-09 06:21:10 UTC
(I looked for duplicate -Wuninitialized bugs but didn't see anything similar)

In the attached minimized testcase I get a clear 'is used uninitialized' warning downgraded to a 'may be used uninitialized' warning on unrelated code changes.

The program compiles correctly with the following flags: -O3 -Wall
To move one function definition into a namespace, add -DBAD_NAMESPACE and get the wrong warning.
Reordering/removing/adding/changing the sizes of local variables makes the warning restore to 'is used uninitialized', one example can be enabled by -DGOOD_ORDER

This is a regression since 4.3 as 4.2 always gives a 'is used uninitialized' warning. I tested with the following compilers from SVN on amd64 and x86 architectures:

g++-trunk (GCC) 4.6.0 20100901 (experimental) ==> BAD
g++-4.5.x (GCC) 4.5.2 20100901 (prerelease) ==> BAD
g++-4.4.x (GCC) 4.4.5 20100824 (prerelease) ==> BAD
g++-4.3.x (GCC) 4.3.6 20100824 (prerelease) ==> BAD
g++-4.2.x (GCC) 4.2.5 20090330 (prerelease) ==> OK

+ g++-4.5.x -std=c++0x -O3 -Wall -c PRmbuuitf.cpp
PRmbuuitf.cpp: In function 'void test()':
PRmbuuitf.cpp:66:25: warning: 'b$t$MBUUITF' is used uninitialized in this function
PRmbuuitf.cpp:64:5: note: 'b$t$MBUUITF' was declared here
+ g++-4.5.x -std=c++0x -O3 -Wall -c PRmbuuitf.cpp -DBAD_NAMESPACE
PRmbuuitf.cpp: In function 'void test()':
                                            vvv
PRmbuuitf.cpp:66:25: warning: 'b$t$MBUUITF' may be used uninitialized in this function
                                            ^^^
PRmbuuitf.cpp:64:5: note: 'b$t$MBUUITF' was declared here
+ g++-4.5.x -std=c++0x -O3 -Wall -c PRmbuuitf.cpp -DBAD_NAMESPACE -DGOOD_ORDER
PRmbuuitf.cpp: In function 'void test()':
PRmbuuitf.cpp:66:25: warning: 'b$t$MBUUITF' is used uninitialized in this function
PRmbuuitf.cpp:64:5: note: 'b$t$MBUUITF' was declared here

+ g++-4.2.x -O3 -Wall -c PRmbuuitf.cpp -DBAD_NAMESPACE
PRmbuuitf.cpp: In function 'void test()':
PRmbuuitf.cpp:66: warning: 'b.B::t.T::MBUUITF' is used uninitialized in this function
PRmbuuitf.cpp:64: note: 'b.B::t.T::MBUUITF' was declared here
Comment 1 Andreas Beckmann 2010-09-09 06:24:51 UTC
Created attachment 21746 [details]
minimized testcase
Comment 2 Manuel López-Ibáñez 2010-09-09 08:00:56 UTC
In any case, this is a clear regression of the pretty printer.
Comment 3 Jakub Jelinek 2010-09-09 11:56:46 UTC
I don't see any problem.  All of current trunk, 4.5 and 4.4 print it as
b.B::t.T::MBUUITF
rather than
b$t$MBUUITF
and the other difference in the warning message is not caused by unrelated code changes, but actually very much related.
With -UBAD_NAMESPACE ::f() function is defined in the current TU and thus the compiler knows it doesn't throw and that D::D() doesn't throw either, with -DBAD_NAMESPACE ::f() is only declared and so the compiler doesn't know it it throws or doesn't, and similarly for D::D().  The is used uninitialized warning is emitted only in basic blocks that are always executed (with -UBAD_NAMESPACE if A::A() is called, it will always pass the uninitialized var to C::g(int);
with -DBAD_NAMESPACE if ::f() throws then that wouldn't happen.