$ cat t.c
extern int foo_p (int *, int);
extern int foo (int, int);
extern void bar (void);
int foo_p (int *x, int y)
{
int a;
if (*x) a = y;
bar ();
if (*x) return a;
bar ();
return -1;
}
int foo (int x, int y)
{
int a;
if (x) a = y;
bar ();
if (x) return a;
bar ();
return -1;
}
$
$ gcc-4.4 -S -O2 -W -Wall -Wextra t.c
t.c: In function ‘foo_p’:
t.c:7: warning: ‘a’ may be used uninitialized in this function
$
$ gcc-4.6 -S -O2 -W -Wall -Wextra t.c
t.c: In function ‘foo_p’:
t.c:7:7: warning: ‘a’ may be used uninitialized in this function [-Wuninitialized]
$
$ ./xgcc -B. -S -O2 -W -Wall -Wextra t.c --version
xgcc (GCC) 4.8.0 20121226 (experimental) [trunk revision 194725]
Copyright (C) 2012 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.
$ ./xgcc -B. -S -O2 -W -Wall -Wextra t.c
t.c: In function 'foo_p':
t.c:7:7: warning: 'a' may be used uninitialized in this function [-Wmaybe-uninitialized]
int a;
^
$
In foo_p, the compiler cannot know whether bar will change the value at *x and the warning is valid. In foo, which is your example, there is no warning. In general, there will be no warning if the compiler can prove that the code in your "/* later */" doesn't change the result of the tested conditional. This is implemented in tree-ssa-uninit.c.
Still, it's true that there will be false positives, or missed warnings. Proving whether a variable is used uninitialized is not an easy problem.