Bug 49754 - Wuninitialized does not work with structs/unions/arrays
Summary: Wuninitialized does not work with structs/unions/arrays
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.5.1
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL: https://bugzilla.novell.com/show_bug....
Keywords:
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
 
Reported: 2011-07-15 06:16 UTC by Christopher Yeleighton
Modified: 2017-09-17 18:05 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-10-04 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Christopher Yeleighton 2011-07-15 06:16:27 UTC
The compiler gcc currently warns about uninitialized scalar variables but not
about compound variables.

== Steps to Reproduce ==
  1. 
{ cat>foo.c<<'/* EOF */' && gcc -Wall -pedantic-errors foo.c; }
struct i { int x; };
struct i foo () { struct i x; return x; }
int bar () { int y; return +y; }
/* EOF */

== Actual Results ==  
foo.c: In function ‘bar’:
foo.c:3:21: warning: ‘y’ is used uninitialized in this function


== Expected Results ==  
foo.c: In function ‘foo’:
foo.c:2:?: warning: ‘x’ is used uninitialized in this function
foo.c: In function ‘bar’:
foo.c:3:21: warning: ‘y’ is used uninitialized in this function
Comment 1 Jonathan Wakely 2011-07-15 08:36:30 UTC
(In reply to comment #0)
> == Expected Results ==  
> foo.c: In function ‘foo’:
> foo.c:2:?: warning: ‘x’ is used uninitialized in this function

It should really warn if 'x.i' is used uninitialized, not 'x'
Comment 2 Christopher Yeleighton 2011-07-15 09:35:42 UTC
(In reply to comment #1)
> (In reply to comment #0)
> > == Expected Results ==  
> > foo.c: In function ‘foo’:
> > foo.c:2:?: warning: ‘x’ is used uninitialized in this function
> 
> It should really warn if 'x.i' is used uninitialized, not 'x'

Since (x) is uninitialized, so is (x.i).  It is impossible to recognize the problem when (x.i) is eventually accessed by a client of foo:

{
struct i x = foo (); 
printf ("%i", +x.i);
}
Comment 3 Jonathan Wakely 2011-07-15 09:56:49 UTC
(In reply to comment #2)
> Since (x) is uninitialized, so is (x.i).

But what if x.i gets initialized, is x still uninitialized?


struct X { int i; };
struct Y { int i; int j; };

int main()
{
  X x;
  x.i = 0;   // is 'x' initialized now?
  Y y;
  y.i = 0;   // is 'y' initialized now?
  y.j = 0;   // is 'y' initialized now?
}


It would be possible to track the initialization of each subobject *and* the aggregate, but it would be more overhead
Comment 4 Jonathan Wakely 2011-07-15 10:16:12 UTC
Just to be clear - I completely agree that uninit'd warnings need improving, I'm not objecting to that.  But in my experience (mostly C++) I'd prefer to have it tracked at the more fine-grained level of sub-objects.
Comment 5 Christopher Yeleighton 2011-07-15 11:00:28 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > Since (x) is uninitialized, so is (x.i).
> 
> But what if x.i gets initialized, is x still uninitialized?

If (x.i) denotes an object type and the initial value means "x is empty" then x is initialized.

> 
> struct X { int i; };
> struct Y { int i; int j; };
> 
> int main()
> {
>   X x;
>   x.i = 0;   // is 'x' initialized now?
>   Y y;
>   y.i = 0;   // is 'y' initialized now?
>   y.j = 0;   // is 'y' initialized now?
> }
> 
> 
> It would be possible to track the initialization of each subobject *and* the
> aggregate, but it would be more overhead

I have already bumped into this using arrays, where GCC does emit a warning although it should not:

int a [02]; 
for (a [0] = 0;;) if (a [0]) printf ("%d", +a [1]); else a [0] = a [1] = 01;
Comment 6 Manuel López-Ibáñez 2012-10-04 08:23:24 UTC
This is a problem of representation. Struct/unions/arrays are represented as memory operations, and Wuninitialized does not (generally) work on them. It may warn in some corner cases if the accesses can be converted into scalar variables, but in general it doesn't work.

I am not even sure if the current middle-end representation can tell whether the memory is uninitialized and never initialized up to the point of use. That would be the first thing to implement.