Bug 46853

Summary: gcc fails to warn about uninitialized variable
Product: gcc Reporter: gcc-bugs
Component: cAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: gcc-bugs, manu
Priority: P3    
Version: 4.4.5   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

Description gcc-bugs 2010-12-08 17:18:49 UTC
With the code below gcc warns of uninitialised variable only when not nested in a loop.

The test case is simple enough. I think gcc should be able to check for this.  

The 'FOR_LOOP' test case has also been checked with GNU C (GCC) version 4.4.3 (arm-unknown-elf), and gcc (Debian 4.4.5-8) 4.4.5, with the same behaviour as below.

$ cat gcc_test.c
int func(void);

int main(void)
{
  int foo;

  foo = func();

  return foo;
}

int func(void)
{
  int foo;

#if defined (FOR_LOOP)

  int i;

  for (i = 0; i < 5; i++)

#elif defined (WHILE_LOOP)

  while(1)

#endif

  {
    if (foo == 0x00)            /* uninitialised use */
    {
      foo = 0xFF;
    }
  }

  return foo;
}
$ gcc gcc_test.c -Os -Wall -Wextra -Wuninitialized
gcc_test.c: In function `func':
gcc_test.c:29: warning: `foo' is used uninitialized in this function
$ gcc gcc_test.c -Os -Wall -Wextra -Wuninitialized -DFOR_LOOP
$ gcc gcc_test.c -Os -Wall -Wextra -Wuninitialized -DWHILE_LOOP
$ gcc --version
gcc (GCC) 4.3.4 20090804 (release) 1
Copyright (C) 2008 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.

$
Comment 1 Richard Biener 2010-12-08 20:35:19 UTC
This is a dup of xxxxx, we apply conditional constant and copy propagation
which will optimize the uninitialized use away before we have a chance to warn.
Comment 2 gcc-bugs 2010-12-09 08:36:46 UTC
The variable can be optimised away in the WHILE_LOOP test case so in effect the variable 'foo' is never used uninitialised.

However with the FOR_LOOP test case it is not possible to optimise away the variable 'foo' and it is unclear what value the function will eventually return.

In theory the for loop and the variable 'i' could be optimised away, but I doubt gcc actually does this.  However imagine that gcc did so then the FOR_LOOP test case should generate the same warning as the basic test case, but it does not.

Is it unreasonable to expect gcc to warn about uninitialised use of the variable in such cases where it is not optimised away?
Comment 3 Dmitry Gorbachev 2010-12-09 14:36:15 UTC
There are already many bug reports about missing "used uninitialized" warnings (such as my PR42905). It seems that the GCC devs do not take them all to heart.

> However with the FOR_LOOP test case it is not possible
> to optimise away the variable 'foo' and it is unclear
> what value the function will eventually return.

> In theory the for loop and the variable 'i' could be
> optimised away, but I doubt gcc actually does this.

In fact, GCC optimises func into

int func(void)
{
  return 0xFF;
}

Undefined behavior, so it's correct.
Comment 4 Jonathan Wakely 2010-12-09 14:40:12 UTC
(In reply to comment #3)
> It seems that the GCC devs do not take them all to heart.

No, they just don't have the resources to fix them all.  It's not an easy problem.
Comment 5 Manuel López-Ibáñez 2010-12-09 14:45:18 UTC
(In reply to comment #3)
> There are already many bug reports about missing "used uninitialized" warnings
> (such as my PR42905). It seems that the GCC devs do not take them all to heart.

Fixing those bugs would require major work. There is no enough people to do that work. And those bugs are not considered important by core devs.

You may have more luck with clang-analyzer, but I think it is still quite green for C++ bugs.

> In fact, GCC optimises func into
> 
> int func(void)
> {
>   return 0xFF;
> }
> 
> Undefined behavior, so it's correct.

Almost 99% sure this is PR 18501.

However your PR42905 seems a novel case to me, no idea why it was closed.

*** This bug has been marked as a duplicate of bug 18501 ***