Bug 59500 - Bogus maybe-uninitialized (|| converted to nested-if)
Summary: Bogus maybe-uninitialized (|| converted to nested-if)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
 
Reported: 2013-12-13 21:08 UTC by Andy Lutomirski
Modified: 2017-03-31 21:36 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-09-12 00:00:00


Attachments
Headerless reproducer (c++ only) (122 bytes, text/x-c++src)
2014-09-12 18:43 UTC, Andy Lutomirski
Details
Output from g++ -O2 -Wall -fdump-tree-all-all-lineno pr59500.cc (994 bytes, text/plain)
2014-09-12 18:44 UTC, Andy Lutomirski
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andy Lutomirski 2013-12-13 21:08:32 UTC
I would have sworn that there was a bug open about this, but I can't find it, and this bug has been annoying me for years.

Compiling this code with g++ -O2 -Wall:

#ifndef __cplusplus
#include <stdbool.h>
#endif

extern int intval();
extern bool cond();

int main()
{
  bool valid = false;
  int value;

  if (cond()) {
    valid = true;
    value = intval();
  }

  while (!valid || intval() < value)
    ;

  return 0;
}

says:

trivial_uninit_warning.cc: In function ‘int main()’:
trivial_uninit_warning.cc:18:17: warning: ‘value’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   while (!valid || intval() < value)


Oddly, compiling exactly the same code in C (instead of C++) does not warn.

This seems quite sensitive to exactly what the code is doing.  IIRC the issue is that the "load" of value is moved ahead of the check of valid by the optimizer (which is entirely valid), but then that load appears to access an uninitialized value and warns.
Comment 1 Andy Lutomirski 2014-01-14 23:51:54 UTC
This might be a duplicate of PR56574
Comment 2 Manuel López-Ibáñez 2014-09-12 13:55:59 UTC
Could you remove the stdbool.h header (just use char or int, it should not change the bug)? Also could you compile with -fdump-tree-all-all-lineno and paste/attach the dump file that looks similar to test.c.XXXt.uninitX? It should show clearly whether it is a duplicate or a different issue.
Comment 3 Andy Lutomirski 2014-09-12 18:43:42 UTC
Created attachment 33484 [details]
Headerless reproducer (c++ only)
Comment 4 Andy Lutomirski 2014-09-12 18:44:49 UTC
Created attachment 33485 [details]
Output from g++ -O2 -Wall -fdump-tree-all-all-lineno pr59500.cc
Comment 5 Manuel López-Ibáñez 2014-09-12 21:03:45 UTC
(In reply to Andy Lutomirski from comment #1)
> This might be a duplicate of PR56574

I think not. In this case the problem is that

# value = PHI<value(D),intval()>
if (!valid || intval() < value)

is converted to

# value = PHI<value(D),intval() > 
if(!valid)
else if (intval() < value)

and I think the uninit pass is not smart enough to realize that the use is guarded by valid != 0 but the default definition implies valid == 0.

Perhaps it is also a missed-optimization, since "if(cond())" could jump directly to "if (intval() < value)".
Comment 6 Jeffrey A. Law 2017-03-31 19:23:23 UTC
This was fixed a few years ago by:

Author: amker <amker@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed Feb 26 01:49:35 2014 +0000

            PR target/60280
            * tree-cfgcleanup.c (tree_forwarder_block_p): Protect loop
            preheaders and latches only if requested.  Fix latch if it
            is removed.
            * tree-ssa-dom.c (tree_ssa_dominator_optimize): Set
            LOOPS_HAVE_PREHEADERS.
    
            PR target/60280
            * gnat.dg/renaming5.adb: Change to two expected gotos.
            * gcc.dg/tree-ssa/pr21559.c: Change back to three expected
            jump threads.
            * gcc.dg/tree-prof/update-loopch.c: Check two "Invalid sum"
            messages for removed basic block.
            * gcc.dg/tree-ssa/ivopt_1.c: Fix unreliable scanning string.
            * gcc.dg/tree-ssa/ivopt_2.c: Ditto.
            * gcc.dg/tree-ssa/ivopt_3.c: Ditto.
            * gcc.dg/tree-ssa/ivopt_4.c: Ditto.
Comment 7 Jeffrey A. Law 2017-03-31 21:36:26 UTC
Per c#6.