Bug 58488 - -Wuninitialized is useless for a variable whose address is later taken
Summary: -Wuninitialized is useless for a variable whose address is later taken
Status: RESOLVED WONTFIX
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.8.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 58711 (view as bug list)
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
 
Reported: 2013-09-20 23:55 UTC by Eric Blake
Modified: 2013-10-30 20:47 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Blake 2013-09-20 23:55:39 UTC
Here's a simple example of where -Wuninitialized is rather useless at default optimization:

$ cat foo.c
#include <stdlib.h>

int main(void) {
    char *oops;
    free(oops);
    void *other =
#ifdef RELIABLE
        NULL
#else
        &oops
#endif
        ;
    return !other;
}

$ gcc -Werror -Wall -Wuninitialized -o foo -c foo.c
$ gcc -Werror -Wall -Wuninitialized -o foo -c foo.c -DRELIABLE
foo.c: In function ‘main’:
foo.c:5:9: error: ‘oops’ is used uninitialized in this function [-Werror=uninitialized]
     free(oops);
         ^
cc1: all warnings being treated as errors
$ gcc -Werror -Wall -Wuninitialized -o foo -c foo.c -O2
foo.c: In function ‘main’:
foo.c:5:9: error: ‘oops’ is used uninitialized in this function [-Werror=uninitialized]
     free(oops);
         ^
cc1: all warnings being treated as errors
$ gcc -Werror -Wall -Wuninitialized -o foo -c foo.c -DRELIABLE -O2
foo.c: In function ‘main’:
foo.c:5:9: error: ‘oops’ is used uninitialized in this function [-Werror=uninitialized]
     free(oops);
         ^
cc1: all warnings being treated as errors

I understand that -O2 enables better uninitialization checks, but I find it quite awkward that even without -O2, the mere taking an address of a variable hides it from the uninit checker.  My end goal is to have a macro that does a one-shot evaluation of its argument:

#define FREE(x) { typeof(x) *_x = &(x); free(*_x); *_x = NULL; }

for safety, but that macro kills -Wuninit checking by virtue of the fact that it takes the address of the pointer.  Even if I limit myself to a macro that evaluates its argument more than once (and forcing me to audit code to avoid FREE(side-effects) - if only there were a way to make the compiler automatically barf if it encounters side effects in a macro argument), I am unable to come up with a way to get the uninit checking that gcc provides regardless of optimization without also having the safety of ensuring the pointer isn't abused after the fact.
Comment 1 Manuel López-Ibáñez 2013-09-22 10:48:57 UTC
So you want the warning even with -O0?

I am not sure that, without optimization, the internal representation can detect this case.
Comment 2 Manuel López-Ibáñez 2013-09-22 15:04:06 UTC
Note that this has nothing to do with the fact that the uninitialized var is a pointer:

void test(char);

int main(void) {
  char oops;
  test(oops);
  char *other = &oops;
  return !other;
}
Comment 3 Eric Blake 2013-09-23 16:16:34 UTC
Since the engine is able to warn at -O0 when I _don't_ take the address, I don't see why the warning is lost by the mere action of taking the address.
Comment 4 Jakub Jelinek 2013-09-23 16:31:08 UTC
The warning machinery is only able to warn about vars in SSA form, vars which must live in memory can't be warned on easily.  So, for such variables you only get warnings if the compiler is able as part of some optimization make the var non-addressable (e.g. inlining and propagation can help that, etc.), or scalar replacement of aggregates is able to break appart larger aggregates and use SSA form for those.  Thus, you get better warnings with optimizations.
Comment 5 Manuel López-Ibáñez 2013-10-13 12:33:39 UTC
*** Bug 58711 has been marked as a duplicate of this bug. ***
Comment 6 Jeffrey A. Law 2013-10-30 20:47:35 UTC
Jakub's comments in c#4 are 100% accurate.  This isn't something we're going to change/fix.  Sorry.