Bug 54554

Summary: fails to warn for uninitialized var within loop always taken at -O0
Product: gcc Reporter: Dimitris Papavasiliou <dpapavas>
Component: cAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: dominik.muth, manu, pawel_sikora
Priority: P3    
Version: 4.7.1   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2012-09-12 00:00:00
Bug Depends on:    
Bug Blocks: 24639    
Attachments: The output of the command line used to compile the snippet to stderr.

Description Dimitris Papavasiliou 2012-09-12 09:16:42 UTC
Created attachment 28176 [details]
The output of the command line used to compile the snippet to stderr.

When compiling the snippet below:

---8<------8<------8<------8<------8<------8<------8<------8<---

extern int printf (__const char *__restrict __format, ...);

int main()
{
    int j;

    for (j = 0 ; j < 10 ; j += 1) {
        int i;

        printf ("%d\n", i);
        i = 1;
    }
    
    return 0;
}

---8<------8<------8<------8<------8<------8<------8<------8<---

GCC fails to detect the use of an uninitialized variable.  The command line used to compile it is:

gcc -v -save-temps -Wall -Wextra -O0 -g -ansi -pedantic foo.c

Output to stderr has been attached.  I won't attach the .i file as it simply seems to contain a copy of the source.  Let me know if you need it.

Bug 52523 seems to be related if not identical but I'm still submitting this as this is C code not C++.
Comment 1 Richard Biener 2012-09-12 09:47:16 UTC
By means of the assignment i becomes an induction variable and at -O0 we do
not warn for "maybe used uninitialized".  With optimization the use is
constant-propagated out.

Thus, this is a known issue, not really the same as PR52523
Comment 2 Dimitris Papavasiliou 2012-09-12 10:19:20 UTC
Specifying -O does indeed produce a warning if i is not assigned a constant value (for instance i = rand(); ).  Omitting -O and specifying -Wmaybe-uninitialized does not produce anything though.  Does that mean that warnings about possibly uninitialized variables are not supported at all, even if explicitly requested by the user when not optimizing?  If that is the case then perhaps this should be documented in the manual.  The latest version just mentions this for -Wmaybe-uninitialized:

"This warning is enabled by -Wall or -Wextra."
Comment 3 Manuel López-Ibáñez 2013-01-04 10:27:53 UTC
GCC should warn without optimization since the code is always executed. There are several issue conflated here that prevent warning, but the most crucial is that GCC does not know that the loop is always executed at least once.
Comment 4 Dimitris Papavasiliou 2013-01-04 12:41:02 UTC
Still even without knowing that a "may be used uninitialized" warning can be issued in any case.
Comment 5 Manuel López-Ibáñez 2013-01-04 12:49:39 UTC
(In reply to comment #4)
> Still even without knowing that a "may be used uninitialized" warning can be
> issued in any case.

GCC does not warn if it can prove that the code is never executed. But it doesn't even try to prove that without optimization enabled, so it doesn't warn. Otherwise, it would warn for obvious things like:

int d;
if (0) return d;

and people will complain.
Comment 6 Dimitris Papavasiliou 2013-01-04 14:50:32 UTC
Well this seems to be a core decision regarding the way GCC warnings work (which probably has more far-reaching consequences) but just for the sake of argument, I don't see why people should complain even in such a case.  The only use I can think of for code such as the above is temporarily switching of a statement but, apart from the fact that this can be more efficiently done with preprocessor directives, the thing is that temporarily disabling a statement in this way is meaningful if it is expected that it will be re-enabled at some time in the future.  If that would lead to broken code there's not much of a point.

I don't mean to dictate the coding-style others should use of course but still it seems to me like a small price to pay for avoiding obscure stochastic bugs that can take hours of debugging to locate (especially given the fact that there's good reason to disable optimizations when debugging code).
Comment 7 Marek Polacek 2014-04-09 10:48:56 UTC
*** Bug 60791 has been marked as a duplicate of this bug. ***
Comment 8 Manuel López-Ibáñez 2014-04-09 11:03:56 UTC
(In reply to Dimitris Papavasiliou from comment #6)
> I don't mean to dictate the coding-style others should use of course but
> still it seems to me like a small price to pay for avoiding obscure
> stochastic bugs that can take hours of debugging to locate (especially given
> the fact that there's good reason to disable optimizations when debugging
> code).

It should be possible to run the pass that triggers -Wmaybe-uninitialized warning without optimization, but it will be very noisy. You could explore the option of keeping it disabled at -O0 unless the user requests it by an explicit -Wmaybe-uninitialized. But you should run some tests to see how noisy/useful that would be. My guess is that a lot more noisy than useful.
Comment 9 Dominik Muth 2014-04-10 07:11:58 UTC
Please note that in Bug 60791 no warning is given even with -O3 (except when using a legacy version of gcc).