User account creation filtered due to spam.

Bug 56748 - Bogus uninitialized warning with nested if condition
Summary: Bogus uninitialized warning with nested if condition
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: diagnostic
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
Reported: 2013-03-26 20:26 UTC by Rich Townsend
Modified: 2017-03-31 21:34 UTC (History)
3 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed:

Sample code producing bogus warning (158 bytes, text/x-fortran)
2013-03-26 20:26 UTC, Rich Townsend

Note You need to log in before you can comment on or make changes to this bug.
Description Rich Townsend 2013-03-26 20:26:34 UTC
Created attachment 29736 [details]
Sample code producing bogus warning

In the attached code, compilation with the following args:

gfortran -O2 -fcheck=all -Wall -c test_uninit.f90

...produces the following warning:

test_uninit.f90: In function ‘mysub’:
test_uninit.f90:13:0: warning: ‘b.0’ may be used uninitialized in this function [-Wmaybe-uninitialized]
      print *, b

The warning goes away if any of the following modifications are made:

*) any of the compilation flags is omitted
*) the stop statement in the code is commented out
*) the variable 'b' is made non-optional (and the PRESENT check is removed)
*) the variable 'b' is made a scalar

gfortran -v:
Using built-in specs.
Target: x86_64-apple-darwin11.4.2
Configured with: ./configure CC='gcc -D_FORTIFY_SOURCE=0' --build=x86_64-apple-darwin11.4.2 --prefix=/Applications/madsdk --with-gmp=/Applications/madsdk --with-mpfr=/Applications/madsdk --with-mpc=/Applications/madsdk --enable-languages=c,c++,fortran --disable-multilib
Thread model: posix
gcc version 4.8.0 20130314 (experimental) (GCC)
Comment 1 Tobias Burnus 2013-03-27 08:26:31 UTC
First remark: Bogus uninitialized warnings can not always be prevented. - It is a extremely complex problem, where a few false warnings (and many missed warnings) are unavoidable. Still, one should do better.

If one looks at the dump (-fdump-tree-original, i.e. a C-like output of the internal representation), one sees:

mysub (struct array1_integer(kind=4) & restrict a,
       struct array1_integer(kind=4) * b)

  if (b != 0B && (integer(kind=4)[0:] * restrict) b->data != 0B)
        b.0 = (integer(kind=4)[0:D.1925] * restrict) b->data;
  if (b != 0B && (integer(kind=4)[0:] * restrict) b->data != 0B)
              if (b != 0B && (integer(kind=4)[0:] * restrict) b->data != 0B)
                  // Here are some run-time checks, enabled by -fcheck=all
 = (void *) &(*b.0)[0];
          _gfortran_transfer_array_write (&dt_parm.9, &parm.10, 4, 0);

As all "if" conditions are the same, b.0 is never uninitialized. However, nesting the same "b != NULL" seems to confuse the uninitialized diagnostic.
Comment 2 Manuel López-Ibáñez 2014-09-11 14:14:51 UTC
There is a uninit dump file that explains what the uninit pass is doing. It would be helpful to see if the condition is in fact too complex or it has been transformed by some optimization pass into something that cannot be handled.
Comment 3 Jeffrey A. Law 2017-03-31 21:34:45 UTC
Not sure when this was fixed, but it works fine on the trunk.  VRP1/DOM2 are able to thread the conditional branches (which removes unexecutable paths) with the net result is all the uninitialized uses of b.0 are ultimately removed.