Bug 57287 - [4.9 Regression] Bogus uninitialized warning with abnormal control flow
Summary: [4.9 Regression] Bogus uninitialized warning with abnormal control flow
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 4.9.0
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2013-05-15 12:11 UTC by hmb
Modified: 2013-09-03 07:53 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-05-15 00:00:00


Attachments
preprocessed source (134.34 KB, text/plain)
2013-05-23 11:03 UTC, Richard Biener
Details
somewhat reduced testcase (5.65 KB, text/plain)
2013-05-23 14:34 UTC, Richard Biener
Details
more reduced (1.60 KB, text/plain)
2013-05-23 14:42 UTC, Richard Biener
Details
preprocessed source code (124.25 KB, text/plain)
2013-05-27 10:17 UTC, hmb
Details

Note You need to log in before you can comment on or make changes to this bug.
Description hmb 2013-05-15 12:11:18 UTC
While I was building the latest GDB CVS source code with
gcc (GCC) 4.9.0 20130513 (experimental)
with building step
with building step 

$CC="/home/mbilal/gcc-svn/install/bin/gcc" ./../src/configure
--prefix=/home/mbilal/commit-gdb-cvs/install

$ make

I got errors

 -MF .deps/py-framefilter.Tpo -fno-strict-aliasing -DNDEBUG -fwrapv
.././../src/gdb/python/py-framefilter.c
In file included from .././../src/gdb/python/py-framefilter.c:24:0:
.././../src/gdb/python/py-framefilter.c: In function ‘enumerate_locals’:
.././../src/gdb/exceptions.h:152:31: error: ‘buf’ may be used uninitialized in
this function [-Werror=maybe-uninitialized]
        EXCEPTIONS_SIGJMP_BUF *buf = \
                               ^
.././../src/gdb/exceptions.h:152:31: note: ‘buf’ was declared here
        EXCEPTIONS_SIGJMP_BUF *buf = \
                               ^
.././../src/gdb/python/py-framefilter.c:839:7: note: in expansion of macro
‘TRY_CATCH’
       TRY_CATCH (except, RETURN_MASK_ALL)
       ^
.././../src/gdb/exceptions.h:152:31: error: ‘buf’ may be used uninitialized in
this function [-Werror=maybe-uninitialized]
        EXCEPTIONS_SIGJMP_BUF *buf = \
                               ^
.././../src/gdb/exceptions.h:152:31: note: ‘buf’ was declared here
        EXCEPTIONS_SIGJMP_BUF *buf = \
                               ^
.././../src/gdb/python/py-framefilter.c:782:7: note: in expansion of macro
‘TRY_CATCH’
       TRY_CATCH (except, RETURN_MASK_ALL)
       ^
.././../src/gdb/exceptions.h:152:31: error: ‘buf’ may be used uninitialized in
this function [-Werror=maybe-uninitialized]
        EXCEPTIONS_SIGJMP_BUF *buf = \
                               ^
.././../src/gdb/exceptions.h:152:31: note: ‘buf’ was declared here
        EXCEPTIONS_SIGJMP_BUF *buf = \
                               ^
.././../src/gdb/python/py-framefilter.c:762:4: note: in expansion of macro
‘TRY_CATCH’
    TRY_CATCH (except, RETURN_MASK_ALL)
    ^
.././../src/gdb/python/py-framefilter.c:732:23: error: ‘locals_cleanups’ may be
used uninitialized in this function [-Werror=maybe-uninitialized]
       struct cleanup *locals_cleanups;
                       ^
.././../src/gdb/python/py-framefilter.c:731:11: error: ‘local_indent’ may be
used uninitialized in this function [-Werror=maybe-uninitialized]
       int local_indent = 8 + (8 * indent);
           ^
cc1: all warnings being treated as errors
make[2]: *** [py-framefilter.o] Error 1
make[2]: Leaving directory `/home/mbilal/commit-gdb-cvs/objdir/gdb'
make[1]: *** [all-gdb] Error 2
make[1]: Leaving directory `/home/mbilal/commit-gdb-cvs/objdir'
make: *** [all] Error 2


But something looks really bogus with errors like

.././../src/gdb/python/py-framefilter.c:731:11: error: ‘local_indent’ may be
used uninitialized in this function [-Werror=maybe-uninitialized]
       int local_indent = 8 + (8 * indent);

First I reported a bug on GDB bugzilla
http://sourceware.org/bugzilla/show_bug.cgi?id=15463#c4
Comment 1 Pedro Alves 2013-05-15 12:43:32 UTC
(Repeating my comment on the GDB bugzilla here)

All these warnings are around setjmp/longjmp.

E.g, with:

.././../src/gdb/python/py-framefilter.c:731:11: error: ‘local_indent’ may be
used uninitialized in this function [-Werror=maybe-uninitialized]
       int local_indent = 8 + (8 * indent);

local_indent is only used in a TRY_CATCH block, meaning, after a setjmp.

I suspect this to be related to this recent setjmp gcc change:

 http://gcc.gnu.org/ml/gcc-patches/2013-05/msg00344.html
Comment 2 Richard Biener 2013-05-15 13:00:04 UTC
Please attach at least one example as preprocessed source.
Comment 3 Pedro Alves 2013-05-22 17:10:02 UTC
hmb,

could you do that?

See instructions here: http://gcc.gnu.org/bugs/
Comment 4 hmb 2013-05-23 10:57:09 UTC
I am attaching the all preprocessed source code of GDB
here is the link https://www.dropbox.com/s/ldml34p3lov867w/gcc-bug.zip
Comment 5 Richard Biener 2013-05-23 11:02:47 UTC
Confirmed with -O2 -Wall.
Comment 6 Richard Biener 2013-05-23 11:03:11 UTC
Created attachment 30172 [details]
preprocessed source
Comment 7 Richard Biener 2013-05-23 14:18:06 UTC
tree-ssa-uninit.c somehow fails to properly handle abnormal edges.

Index: tree-ssa-uninit.c
===================================================================
--- tree-ssa-uninit.c   (revision 199249)
+++ tree-ssa-uninit.c   (working copy)
@@ -1919,7 +1919,8 @@ find_uninit_use (gimple phi, unsigned un
             }
 
           worklist->safe_push (use_stmt);
-          pointer_set_insert (possibly_undefined_names, phi_result);
+         if (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (phi_result))
+           pointer_set_insert (possibly_undefined_names, phi_result);
         }
     }
 
fixes the issue but that doesn't look the very best place to fix it
and it doesn't look fully correct.  It should be enough to not consider
values flowing across abnormal edges - but that's already done (but somehow
not in a complete manner).

I'm trying to reduce the testcase to get a better idea what is going wrong
here.
Comment 8 Richard Biener 2013-05-23 14:34:34 UTC
Created attachment 30175 [details]
somewhat reduced testcase

Autoreduced on level 0.
Comment 9 Richard Biener 2013-05-23 14:42:06 UTC
Created attachment 30176 [details]
more reduced
Comment 10 Richard Biener 2013-05-24 11:01:19 UTC
#include <setjmp.h>
jmp_buf buf;
void foo (int);
void bar (int) __attribute__((leaf));
void enumerate_locals (int indent)
{
  foo (0);
  while (indent--)     
    {
      int local_indent = 8 + (8 * indent);
      if (local_indent != 8)
        {
          setjmp (buf);
          bar (local_indent);
        }
    }
  foo (1);
}


warns about uninitialized local_indent.  The abnormal edges we insert
for foo (0) make undefined values flow into the setjmp block.
Comment 11 Richard Biener 2013-05-24 12:45:37 UTC
Author: rguenth
Date: Fri May 24 12:44:58 2013
New Revision: 199289

URL: http://gcc.gnu.org/viewcvs?rev=199289&root=gcc&view=rev
Log:
2013-05-24  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/57287
	* tree-ssa-uninit.c (compute_uninit_opnds_pos): Disregard
	all SSA names that occur in abnormal PHIs.

	* gcc.dg/pr57287.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/pr57287.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-uninit.c
Comment 12 hmb 2013-05-27 10:15:03 UTC
I got enother error in gdb source code with same building step as I described above:

/home/mbilal/gcc-svn/install/bin/gcc -save-temps -g -O2   -I. -I.././../src/gdb -I.././../src/gdb/common -I.././../src/gdb/config -DLOCALEDIR="\"/home/mbilal/gdb-git/gcc_install_bug_report/share/locale\"" -DHAVE_CONFIG_H -I.././../src/gdb/../include/opcode -I.././../src/gdb/../opcodes/.. -I.././../src/gdb/../readline/.. -I../bfd -I.././../src/gdb/../bfd -I.././../src/gdb/../include -I../libdecnumber -I.././../src/gdb/../libdecnumber  -I.././../src/gdb/gnulib/import -Ibuild-gnulib/import   -DTUI=1  -I/usr/include/python2.7 -I/usr/include/python2.7 -Wall -Wdeclaration-after-statement -Wpointer-arith -Wpointer-sign -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wmissing-prototypes -Wdeclaration-after-statement -Wempty-body -Wformat-nonliteral -Werror -c -o value.o -MT value.o -MMD -MP -MF .deps/value.Tpo .././../src/gdb/value.c
.././../src/gdb/value.c: In function ‘show_convenience’:
.././../src/gdb/value.c:2247:21: error: ‘buf’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
       TRY_CATCH (ex, RETURN_MASK_ERROR)
                     ^
cc1: all warnings being treated as errors
make[2]: *** [value.o] Error 1
make[2]: Leaving directory `/home/mbilal/gdb-git/gcc-obj_bug_report/gdb'
make[1]: *** [all-gdb] Error 2
make[1]: Leaving directory `/home/mbilal/gdb-git/gcc-obj_bug_report'
make: *** [all] Error 2
Comment 13 hmb 2013-05-27 10:17:58 UTC
Created attachment 30201 [details]
preprocessed source code

Attaching the preprocessed source code
Comment 14 meadori 2013-08-19 21:54:37 UTC
(In reply to hmb from comment #13)
> Created attachment 30201 [details]
> preprocessed source code
> 
> Attaching the preprocessed source code

Here is a reduction (as of trunk today):

$ cat test.c
#include <setjmp.h>
#include <stdio.h>

struct node
{
  struct node *next;
  char *name;
} *list;

struct node *list;
struct node *head (void);

sigjmp_buf *bar (void);

int baz (void)
{
  struct node *n;
  int varseen = 0;

  list = head ();
  for (n = list; n; n = n->next)
    {
      if (!varseen)
          varseen = 1;

      sigjmp_buf *buf = bar ();
      __sigsetjmp (*buf, 1);
    }

  if (!varseen)
    return 0;
  return 1;
}
$ i686-pc-linux-gnu-gcc --version
i686-pc-linux-gnu-gcc (GCC) 4.9.0 20130819 (experimental)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ i686-pc-linux-gnu-gcc -Wall -O2 -c test.c
test.c: In function 'baz':
test.c:26:19: warning: 'buf' may be used uninitialized in this function [-Wmaybe-uninitialized]
       sigjmp_buf *buf = bar ();
                   ^
Comment 15 Richard Biener 2013-08-28 08:37:51 UTC
Confirmed.  David, can you have a look here?  I had a hard time following what
exactly to do with the dataflow in the uninit pass for abnormal control flow
(abnormal control flow should be considered receiving an initialized value).

Thanks.
Comment 16 davidxl 2013-08-28 16:58:02 UTC
(In reply to Richard Biener from comment #15)
> Confirmed.  David, can you have a look here?  I had a hard time following
> what
> exactly to do with the dataflow in the uninit pass for abnormal control flow
> (abnormal control flow should be considered receiving an initialized value).
> 
> Thanks.


I looked at it a little. The warning is not from the predicated uninit analysis which checks uses of phi defs.  The warning is emitted from tree-ssa.c:1644 in function warn_uninitialized_vars. It warns about the 'definitely' uninitialized variable that may be executed. In this case it is use of 'buf_16(ab)' in BB3.  Not sure where this statement comes from:

buf_24 = buf_16(ab);

The dot file is attached.

digraph "uninit.c.131t.uninit1" {
overlap=false;
subgraph "baz" {
	color="black";
	label="baz";
	fn_11_basic_block_0 [shape=Mdiamond,style=filled,fillcolor=white,label="ENTRY"];

	fn_11_basic_block_1 [shape=Mdiamond,style=filled,fillcolor=white,label="EXIT"];

	fn_11_basic_block_2 [shape=record,style=filled,fillcolor=lightgrey,label="{ FREQ:10000 |\<bb\ 2\>:\l\
|varseen_11(ab)\ =\ 0;\l\
|_14\ =\ head\ ();\l\
}"];

	fn_11_basic_block_3 [shape=record,style=filled,fillcolor=lightgrey,label="{ FREQ:7100 |\<bb\ 3\>:\l\
|list\ =\ _14;\l\
|buf_24\ =\ buf_16(ab);\l\
|if\ (_14\ !=\ 0B)\l\
\ \ goto\ \<bb\ 4\>;\l\
else\l\
\ \ goto\ \<bb\ 8\>;\l\
}"];

	fn_11_basic_block_4 [shape=record,style=filled,fillcolor=lightgrey,label="{ FREQ:8500 |\<bb\ 4\>:\l\
|#\ varseen_3(ab)\ =\ PHI\ \<1(3),\ 1(6)\>\l\
|#\ n_26(ab)\ =\ PHI\ \<_14(3),\ n_2(ab)(6)\>\l\
|#\ buf_27(ab)\ =\ PHI\ \<buf_24(3),\ buf_7(ab)(6)\>\l\
|buf_21\ =\ bar\ ();\l\
}"];

	fn_11_basic_block_5 [shape=record,style=filled,fillcolor=lightgrey,label="{ FREQ:4250 |\<bb\ 5\>:\l\
}"];

	fn_11_basic_block_6 [shape=record,style=filled,fillcolor=lightgrey,label="{ FREQ:2900 |\<bb\ 6\>:\l\
|#\ n_1(ab)\ =\ PHI\ \<n_15(ab)(2),\ n_26(ab)(4),\ n_26(ab)(5)\>\l\
|#\ varseen_4(ab)\ =\ PHI\ \<varseen_11(ab)(2),\ varseen_3(ab)(4),\ varseen_3(ab)(5)\>\l\
|#\ buf_6(ab)\ =\ PHI\ \<buf_16(ab)(2),\ buf_27(ab)(4),\ buf_21(5)\>\l\
|__sigsetjmp\ (buf_6(ab),\ 1);\l\
|n_19\ =\ n_1(ab)-\>next;\l\
|n_2(ab)\ =\ n_19;\l\
|varseen_5\ =\ varseen_4(ab);\l\
|buf_7(ab)\ =\ buf_6(ab);\l\
|if\ (n_2(ab)\ !=\ 0B)\l\
\ \ goto\ \<bb\ 4\>;\l\
else\l\
\ \ goto\ \<bb\ 7\>;\l\
}"];

	fn_11_basic_block_7 [shape=record,style=filled,fillcolor=lightgrey,label="{ FREQ:1500 |\<bb\ 7\>:\l\
|_25\ =\ varseen_5;\l\
}"];

	fn_11_basic_block_8 [shape=record,style=filled,fillcolor=lightgrey,label="{ FREQ:1500 |\<bb\ 8\>:\l\
|#\ _8\ =\ PHI\ \<_25(7),\ 0(3)\>\l\
|return\ _8;\l\
}"];

	fn_11_basic_block_0:s -> fn_11_basic_block_2:n [style="solid,bold",color=blue,weight=100,constraint=true, label="[100%]"];
	fn_11_basic_block_2:s -> fn_11_basic_block_6:n [style="solid,bold",color=red,weight=10,constraint=true, label="[29%]"];
	fn_11_basic_block_2:s -> fn_11_basic_block_3:n [style="solid,bold",color=blue,weight=100,constraint=true, label="[71%]"];
	fn_11_basic_block_3:s -> fn_11_basic_block_4:n [style="solid,bold",color=black,weight=10,constraint=true, label="[85%]"];
	fn_11_basic_block_3:s -> fn_11_basic_block_8:n [style="solid,bold",color=black,weight=10,constraint=true, label="[15%]"];
	fn_11_basic_block_4:s -> fn_11_basic_block_6:n [style="dotted,bold",color=red,weight=10,constraint=false, label="[50%]"];
	fn_11_basic_block_4:s -> fn_11_basic_block_5:n [style="solid,bold",color=blue,weight=100,constraint=true, label="[50%]"];
	fn_11_basic_block_5:s -> fn_11_basic_block_6:n [style="dotted,bold",color=blue,weight=10,constraint=false, label="[100%]"];
	fn_11_basic_block_6:s -> fn_11_basic_block_4:n [style="solid,bold",color=black,weight=10,constraint=true, label="[85%]"];
	fn_11_basic_block_6:s -> fn_11_basic_block_7:n [style="solid,bold",color=black,weight=10,constraint=true, label="[15%]"];
	fn_11_basic_block_7:s -> fn_11_basic_block_8:n [style="solid,bold",color=blue,weight=100,constraint=true, label="[100%]"];
	fn_11_basic_block_8:s -> fn_11_basic_block_1:n [style="solid,bold",color=black,weight=10,constraint=true, label="[100%]"];
	fn_11_basic_block_0:s -> fn_11_basic_block_1:n [style="invis",constraint=true];
}
}
Comment 17 Richard Biener 2013-08-29 08:18:19 UTC
(In reply to davidxl from comment #16)
> (In reply to Richard Biener from comment #15)
> > Confirmed.  David, can you have a look here?  I had a hard time following
> > what
> > exactly to do with the dataflow in the uninit pass for abnormal control flow
> > (abnormal control flow should be considered receiving an initialized value).
> > 
> > Thanks.
> 
> 
> I looked at it a little. The warning is not from the predicated uninit
> analysis which checks uses of phi defs.  The warning is emitted from
> tree-ssa.c:1644 in function warn_uninitialized_vars. It warns about the
> 'definitely' uninitialized variable that may be executed. In this case it is
> use of 'buf_16(ab)' in BB3.  Not sure where this statement comes from:
> 
> buf_24 = buf_16(ab);

Oh, sorry for not looking close enough again.  It is jump-threading introducing
this copy by duplicating a block with an abnormal PHI.

Not sure why it chooses to duplicate it - I see no jump threads registered
by DOM at -O1 - probably because:

  if (dump_file && (dump_flags & TDF_DETAILS)
      && e->dest != e2->src)
    fprintf (dump_file,
             "  Registering jump thread around one or more intermediate blocks\n");

(gdb) p threaded_edges.vec_->vecdata_[0]->dest
$7 = <basic_block 0x7ffff6e1a4e0 (9)>
(gdb) p threaded_edges.vec_->vecdata_[1]->src
$8 = <basic_block 0x7ffff6e1a4e0 (9)>

but thats the jump threading it performs as it can optimize the if (!varseen)
check.

From looking at the symptoms - warning about buf_16(D)(ab) use in

  buf_24 = buf_16(D)(ab);

it seems simplest to disregard SSA names occuring in abnormal PHIs ...
Comment 18 Richard Biener 2013-08-29 11:20:18 UTC
Author: rguenth
Date: Thu Aug 29 11:20:16 2013
New Revision: 202069

URL: http://gcc.gnu.org/viewcvs?rev=202069&root=gcc&view=rev
Log:
2013-08-29  Richard Biener  <rguenther@suse.de>

	PR middle-end/57287
	* tree-ssa-copy.c (may_propagate_copy): Allow propagating
	of default defs that appear in abnormal PHI nodes.

	* gcc.dg/pr57287-2.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/pr57287-2.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-copy.c
Comment 19 Richard Biener 2013-08-29 11:20:39 UTC
Fixed again.
Comment 20 meadori 2013-08-29 16:33:05 UTC
Confirmed fix.

I can also now build GDB trunk with GCC trunk (both from today).

Thanks Richard!
Comment 21 Jorn Wolfgang Rennecke 2013-09-03 00:51:38 UTC
(In reply to Richard Biener from comment #18)

> Added:
>     trunk/gcc/testsuite/gcc.dg/pr57287-2.c

Why is that using __sigsetjmp ?  That's not a standard function.
E.g. newlib doesn't have it.
Comment 22 rguenther@suse.de 2013-09-03 07:49:35 UTC
On Tue, 3 Sep 2013, amylaar at gcc dot gnu.org wrote:

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57287
> 
> Jorn Wolfgang Rennecke <amylaar at gcc dot gnu.org> changed:
> 
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                  CC|                            |amylaar at gcc dot gnu.org
> 
> --- Comment #21 from Jorn Wolfgang Rennecke <amylaar at gcc dot gnu.org> ---
> (In reply to Richard Biener from comment #18)
> 
> > Added:
> >     trunk/gcc/testsuite/gcc.dg/pr57287-2.c
> 
> Why is that using __sigsetjmp ?  That's not a standard function.
> E.g. newlib doesn't have it.

Sorry, I forgot to change it to setjmp.  Done now.
Comment 23 Richard Biener 2013-09-03 07:53:07 UTC
Author: rguenth
Date: Tue Sep  3 07:53:05 2013
New Revision: 202197

URL: http://gcc.gnu.org/viewcvs?rev=202197&root=gcc&view=rev
Log:
2013-09-03  Richard Biener  <rguenther@suse.de>

	PR middle-end/57287
	* gcc.dg/pr57287-2.c: Use setjmp, not __sigsetjmp.

Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/pr57287-2.c