GCC Bugzilla has been upgraded from version 4.4.9 to 5.0rc3. If you see any problem, please report it to bug 64968.

Bug 21548

Summary: [4.0 regression] Wrong warning about uninitialized variable
Product: gcc Reporter: Andreas Schwab <schwab>
Component: tree-optimizationAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED WONTFIX    
Severity: normal CC: gcc-bugs, James.Juran
Priority: P2 Keywords: diagnostic
Version: 4.0.0   
Target Milestone: 4.0.4   
Host: Target:
Build: Known to work: 4.1.0 4.1.1 4.1.2 3.4.0
Known to fail: 4.0.0 Last reconfirmed: 2006-02-01 04:44:07
Bug Depends on: 21559    
Bug Blocks: 24639    

Description Andreas Schwab 2005-05-13 14:45:57 UTC
$ cat uninit.c 
static int blocksize = 4096; 
 
int bar (int); 
 
void foo (void) 
{ 
  int toread; 
  int bytes; 
  static char eof_reached = 0; 
 
  toread = blocksize; 
 
  while (toread != 0) 
    { 
      bytes = bar (toread); 
      if (bytes <= 0) 
	{ 
	  if (bytes < 0) 
	    continue; 
	  break; 
	} 
      toread -= bytes; 
    } 
 
  if (bytes == 0) 
    eof_reached = 1; 
} 
$ gcc -O2 -Wall -c uninit.c  
uninit.c: In function &#8216;foo&#8217;:  
uninit.c:25: warning: &#8216;bytes&#8217; is used uninitialized in this function  
  
This warning is wrong, since bytes is never used uninitialized as long as  
blocksize is non-zero.
Comment 1 Andrew Pinski 2005-05-13 14:53:19 UTC
hmm, what happens if blocksize is zero when foo is entered.
Comment 2 Andreas Schwab 2005-05-13 14:54:55 UTC
The program logic guarantees that blocksize is never zero. 
Comment 3 Richard Earnshaw 2005-05-13 14:57:48 UTC
The compiler can't be expected to follow that logic.  If blocksize is set to
zero by some magic daemon, then the bytes would be undefined.
Comment 4 Andreas Schwab 2005-05-13 14:59:19 UTC
To clarify, the problem is the "is used" part.  This should be "might be used" 
instead. 
Comment 5 Andreas Schwab 2005-05-13 15:00:35 UTC
It is not _always_ uninitialized. 
Comment 6 Andrew Pinski 2005-05-13 15:01:05 UTC
I also get the warning in 3.4.0 and 3.3.3 with your example, did you reduce it too far?
Comment 7 Richard Earnshaw 2005-05-13 15:05:05 UTC
It's nothing to do with ALWAYS.  It's to do with COULD BE.

There are values that blocksize COULD take that would lead to bytes being
uninitialized.  That's all the warning is telling you.

The compiler is correct to warn.
Comment 8 Andreas Schwab 2005-05-13 15:06:27 UTC
That's why it should say "might be used".  
Comment 9 Andrew Pinski 2005-05-13 21:54:06 UTC
In 4.1.0, we give:
t.c:8: warning: ‘bytes’ may be used uninitialized in this function


So this is only a 4.0.0 bug, let me see how it is considered as "is used".
Comment 10 Andrew Pinski 2005-05-13 22:14:08 UTC
Actually rethinking the problem, the only time we could execute the "if(bytes == 0)" is not going 
through the loop.  Maybe the order in execute_late_warn_uninitialized should be switched around but 
that will not fix this case as we already found that is the only time we can get there.  Hmm, I think we 
are now missing a jump thread opportunity on the mainline then.
Comment 11 Andrew Pinski 2005-05-13 22:16:52 UTC
Maybe not.  Hmm, there might be a wrong code bug here on the 4.0 branch.
Comment 12 Andrew Pinski 2005-05-13 22:23:37 UTC
thinking again out loud:
The function could be changed to (which we seem to be missing on the mainline):
static int blocksize = 4096; 
 
int bar (int); 
 
void foo (void) 
{ 
  int toread; 
  int bytes; 
  static char eof_reached = 0;
 
  toread = blocksize; 
  while (1) 
    { 
      bytes = bar (toread); 
      if (bytes <= 0) 
        { 
          if (bytes < 0) 
            continue; 
          goto temp; 
        } 
      toread -= bytes; 
     if (toread == 0)
       goto temp1;
    } 
   
 
  if (bytes == 0) 
temp:
    eof_reached = 1; 
temp1:
} 

So comming out of the loop bytes will be zero if we break out of it but otherwise cannot, so we can skip 
if statement.  This is a missing optimization on the mainline (someone should look into it) but now my 
comment #10 becomes true and we see that it is always used as uninitized.
Comment 13 Andrew Pinski 2005-05-13 22:44:50 UTC
Note after fixing PR 21559, we will be back to "is used" warning instead of "may be used".
Comment 14 Andrew Pinski 2005-08-22 12:25:57 UTC
As I mentioned, this will be come a regression again once fixing PR 21559.
Comment 15 Gabriel Dos Reis 2007-01-18 11:40:44 UTC
Won't fix for GCC-4.0.x