[Bug middle-end/60488] missing uninitialized warning (address taken, VOP)

2021-04-06 Thread msebor at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60488

Martin Sebor  changed:

   What|Removed |Added

 CC||matthew at wil dot cx

--- Comment #10 from Martin Sebor  ---
*** Bug 88518 has been marked as a duplicate of this bug. ***

[Bug middle-end/60488] missing uninitialized warning (address taken, VOP)

2021-03-30 Thread manu at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60488

--- Comment #9 from Manuel López-Ibáñez  ---
(In reply to Martin Sebor from comment #8)
> You're right, the test cases aren't equivalent, or meant to be.  What I want
> to highlight is that in the test case in comment #6, in g() and other
> similar ones like it the warning is most likely going to be a false
> positive, while in h(), not warning most likely a false negative.  Both of
> these "problems" are due to the same underlying assumption: that a variable
> whose address escapes may be modified by a subsequent call to an unknown
> function.

Sure, but that assumption is not the problem in this PR, since assuming one
thing or the other only matters for distinguishing between "is" and "may be",
but a warning should have been given and it is not given.

[Bug middle-end/60488] missing uninitialized warning (address taken, VOP)

2021-03-29 Thread msebor at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60488

--- Comment #8 from Martin Sebor  ---
You're right, the test cases aren't equivalent, or meant to be.  What I want to
highlight is that in the test case in comment #6, in g() and other similar ones
like it the warning is most likely going to be a false positive, while in h(),
not warning most likely a false negative.  Both of these "problems" are due to
the same underlying assumption: that a variable whose address escapes may be
modified by a subsequent call to an unknown function.

The upshot is that the warning (indeed, all flow-based warnings) should
consider not just what can be proven might happen based on the IL but also the
likelihood with which it might happen.  I'm not saying there's a coding bug in
the implementation of the warning, rather that the heuristics it implements
aren't sufficient to capture this distinction.

[Bug middle-end/60488] missing uninitialized warning (address taken, VOP)

2021-03-27 Thread manu at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60488

--- Comment #7 from Manuel López-Ibáñez  ---
(In reply to Martin Sebor from comment #6)
> The problem is that when the address of a variable escapes, because GCC
> doesn't track when, when the function from which it escapes calls another
> that might access the escaped variable, the warning (as a result of relying
> on the conservative assumptions the optimizers must make) assumes the called
> function initializes the variable.  Another example of this is function h()
> below.

I don't think these are equivalent testcases. It is OK to assume that the
invisible function initializes the variable. The problem arises when there is a
path that never calls the function but GCC does not see that.

The key here is the logical operator splits the possible paths in two. In one
of the paths, b (comment #5) is never initialized, no matter what you assume
about f(). It also happens with a simple if():

int f (int*);
int g(void);
int foo (void)
{
  int b;
  if (g()) {
f();
  }
  return b;
}

However, a similar construct without  works:

int g(void);
int foo (void)
{
  int b;
  if (g()) {
b = g();
  }
  return b;
}

If you look at the VOPs, there is a chain that goes from the VUSE of b to the
VDEF<(D)> through at least one PHI node.

The "return 0" is problematic because CPP (PR18501) will trigger and mess up
things even more. But the above testcases avoid PR18501 and still show this
bug.

[Bug middle-end/60488] missing uninitialized warning (address taken, VOP)

2021-03-26 Thread msebor at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60488

Martin Sebor  changed:

   What|Removed |Added

   Last reconfirmed|2016-08-23 00:00:00 |2021-3-26
  Known to fail|7.0 |11.0

--- Comment #6 from Martin Sebor  ---
Reconfirming with GCC 11.

The problem is that when the address of a variable escapes, because GCC doesn't
track when, when the function from which it escapes calls another that might
access the escaped variable, the warning (as a result of relying on the
conservative assumptions the optimizers must make) assumes the called function
initializes the variable.  Another example of this is function h() below.

The irony (and I'd say the bug) here is that the warning uses the same
conservative assumptions to trigger in cases when an equivalent same situation
might lead to the variable not having been initialized such as in g() below. 
These conflicting assumptions make the warning seem unpredictable.

$ cat z.c && gcc -O2 -S -Wall z.c
void f (void);

int i, *p;

int g (int j)
{
  int x;
  if (i)   // assume i is zero
x = j + 1;

  f ();// assume call sets i

  if (i)
return x;  // issue -Wmaybe-uninitalized

  return i;
}

int h (int j)
{
  int x;

  p =   // address of x escapes

  f ();// assume call sets x

  return x;// avoid warning here
}

z.c: In function ‘g’:
z.c:14:12: warning: ‘x’ may be used uninitialized in this function
[-Wmaybe-uninitialized]
   14 | return x;  // issue -Wmaybe-uninitalized
  |^
z.c:7:7: note: ‘x’ was declared here
7 |   int x;
  |   ^

[Bug middle-end/60488] missing uninitialized warning (address taken, VOP)

2018-09-13 Thread manu at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60488

--- Comment #5 from Manuel López-Ibáñez  ---
Even simpler:

int f (int*);
int g(void);
int foo (void)
{
  int b;

  if (g() && f ())
return 0;

  return b;
}

we have:

  # .MEM_7 = VDEF <.MEM_6(D)>
  # USE = nonlocal null { D.1912 } (escaped)
  # CLB = nonlocal null { D.1912 } (escaped)
  _1 = gD.1908 ();
  if (_1 != 0)
goto ; [33.00%]
  else
goto ; [67.00%]

;;   basic block 6, loop depth 0, count 719407024 (estimated locally), maybe
hot
  # .MEM_11 = PHI <.MEM_7(6), .MEM_8(8)>
  # DEBUG BEGIN_STMT
  # VUSE <.MEM_11>
  _9 = bD.1912;

but uninit pass does not follow the PHI chain for memory ops.

[Bug middle-end/60488] missing uninitialized warning (address taken, VOP)

2017-02-15 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60488

Martin Sebor  changed:

   What|Removed |Added

   Keywords||diagnostic
  Known to fail||4.8.3, 4.9.3, 5.3.0, 6.2.0,
   ||7.0

--- Comment #4 from Martin Sebor  ---
You're right that the goto isn't essential here.  The same problem can be
demonstrated in the simplified test case below.  When f() && f() evaluates
to true (and assuming f() initializes what it points to) there "exists a path
from the function entry to a use of the variable that is initialized."  But
f() evaluates to false f() is not called then "there exists a path for
which b is not initialized."  Since there is no way to prove that the second
path is not taken at runtime then, according to the documentation, GCC should
emit a warning.  However, no warning is issued.

int f (int*);

int foo (void)
{
  int a, b;

  if (f () && f ())
return 0;

  return a + b;
}

[Bug middle-end/60488] missing uninitialized warning (address taken, VOP)

2016-08-23 Thread manu at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60488

Manuel López-Ibáñez  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2016-08-23
 Blocks||24639
Summary|missing |missing uninitialized
   |-Wmaybe-uninitialized on a  |warning (address taken,
   |conditional with goto   |VOP)
 Ever confirmed|0   |1

--- Comment #3 from Manuel López-Ibáñez  ---
I don't think the goto has anything to do with it, but there are several bugs
about taking the address of a variable breaking any obvious uninitialized
warnings.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639
[Bug 24639] [meta-bug] bug to track all Wuninitialized issues