User account creation filtered due to spam.

Bug 42145 - bogus "may be used uninitialized" (a || b converted to a|b)
Summary: bogus "may be used uninitialized" (a || b converted to a|b)
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: diagnostic
: 49848 55759 57072 58455 58698 (view as bug list)
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
Reported: 2009-11-22 14:42 UTC by Colin Finck
Modified: 2015-11-26 01:21 UTC (History)
12 users (show)

See Also:
Known to work: 4.1.3, 4.2.4
Known to fail: 4.3.4, 4.4.1, 4.4.2
Last reconfirmed: 2015-11-26 00:00:00

The test case (178 bytes, text/plain)
2009-11-22 14:43 UTC, Colin Finck
The preprocessed test case (208 bytes, text/plain)
2009-11-22 14:44 UTC, Colin Finck

Note You need to log in before you can comment on or make changes to this bug.
Description Colin Finck 2009-11-22 14:42:20 UTC
I'm compiling the attached test case with "gcc version 4.5.0 20091018 (experimental) [trunk revision 152966] (Ubuntu 20091018-0ubuntu1)".
When using the command line "gcc -Wuninitialized -Os -o test test_gccbug.c", I'm getting the following incorrect warning:

test_gccbug.c: In function 'main':
test_gccbug.c:17:6: warning: 'ret' may be used uninitialized in this function

Same happens with different builds of GCC 4.4.2, 4.4.1 and 4.3.4.
No such warning occurs with builds of GCC 4.2.4 and 4.1.3.

This problem does not occur if one or more of the following is done:
- You change the optimization level to -O0 or -O1 (-O2 and -O3 still trigger the bug in this GCC 4.5.0 version, but not always in older versions I've tested)
- You comment out line 10 of the test case
- You change line 22 of the test case to just 'if (!argc)'
Comment 1 Colin Finck 2009-11-22 14:43:46 UTC
Created attachment 19084 [details]
The test case
Comment 2 Colin Finck 2009-11-22 14:44:48 UTC
Created attachment 19085 [details]
The preprocessed test case
Comment 3 Manuel López-Ibáñez 2009-12-30 16:59:18 UTC
This would need conditional PHIs, so a duplicate of PR20968.

GCC never detects that ret is always initialized, it doesn't warn because at low optimization levels we do not warn for PHIs or because CCP (PR18501) just initializes the variable (probably to 1 or 10). There is some differences between the dumps of -O1 and -O2 in the way the logical or is transformed int bitwise-or and how dom1 deals with each of them, but I cannot tell if there is some missing optimization involved.

*** This bug has been marked as a duplicate of 20968 ***
Comment 4 Manuel López-Ibáñez 2013-11-19 09:11:24 UTC
PR20968 was closed, but this one is still valid in some cases. In particular this testcase with -Os produces a warning.

int translate(int in);

int main(int argc, char* argv[])
  int ret;

  if (argc)
    ret = translate(5);

  if (!argc || !ret)
    ret = 1;

  return ret;

The reason is that with -Os, the check "if (!argc || !ret)" is transformed into:

  # ret_1 = PHI <ret_5(D)(2), [pr19085.c : 8:9] ret_8(3)>
  # .MEM_3 = PHI <.MEM_6(D)(2), .MEM_7(3)>
  [pr19085.c : 10:7] # RANGE [0, 1]
  _9 = argc_4(D) == 0;
  [pr19085.c : 10:16] # RANGE [0, 1]
  _10 = ret_1 == 0;
  [pr19085.c : 10:13] # RANGE [0, 1]
  _11 = _10 | _9;
  [pr19085.c : 10:6] if (_11 != 0)
Comment 5 Jeffrey A. Law 2013-11-19 22:16:33 UTC
-Os disables jump threading except for very specific circumstances because the block duplication generally increases code size.  As a result of restricting the optimizer, certain paths through the CFG which are unexecutable have to be left in the CFG which leads to the false positive.
Comment 6 Jeffrey A. Law 2013-11-19 22:18:40 UTC
*** Bug 58698 has been marked as a duplicate of this bug. ***
Comment 7 Jeffrey A. Law 2013-11-19 22:22:53 UTC
*** Bug 58455 has been marked as a duplicate of this bug. ***
Comment 8 Jeffrey A. Law 2013-11-19 22:30:51 UTC
*** Bug 57072 has been marked as a duplicate of this bug. ***
Comment 9 Jeffrey A. Law 2013-11-20 00:42:11 UTC
*** Bug 55759 has been marked as a duplicate of this bug. ***
Comment 10 Jeffrey A. Law 2013-11-20 01:12:56 UTC
*** Bug 49848 has been marked as a duplicate of this bug. ***
Comment 11 Marcel Telka 2014-05-04 22:56:53 UTC
It is reproducible even with -O1:

int f(void);

        int a, b;

        a = f();
        if (a)
                b = f();

        if (a && b)
                return 1;

        return 0;

$ gcc -O1 -Wuninitialized -c a.c
a.c: In function 'main':
a.c:12:15: warning: 'b' may be used uninitialized in this function [-Wmaybe-uninitialized]
         if (a && b)
$ gcc -v
Using built-in specs.
Target: sparc-sun-solaris2.11
Configured with: /ws/builds2/jenkins/src/du/dilos-userland-review/components/gcc48/gcc-4.8.2/configure --prefix=/usr/gcc/4.8 --mandir=/usr/gcc/4.8/share/man --bindir=/usr/gcc/4.8/bin --libdir=/usr/gcc/4.8/lib --sbindir=/usr/gcc/4.8/sbin --infodir=/usr/share/info --without-gnu-as --with-as=/usr/bin/as --build=sparc-sun-solaris2.11 --infodir=/usr/gcc/4.8/share/info --libexecdir=/usr/gcc/4.8/lib --enable-languages=c,c++,fortran,objc --enable-shared --enable-targets=sparcv9-sun-solaris2.11 --without-gnu-ld --with-ld=/usr/bin/ld
Thread model: posix
gcc version 4.8.2 (GCC)