Summary: | Wuninitialized does not work with structs/unions/arrays | ||
---|---|---|---|
Product: | gcc | Reporter: | Christopher Yeleighton <giecrilj> |
Component: | middle-end | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | enhancement | CC: | dimhen, manu, matt, msebor |
Priority: | P3 | ||
Version: | 4.5.1 | ||
Target Milestone: | --- | ||
URL: | https://bugzilla.novell.com/show_bug.cgi?id=705160#c1 | ||
See Also: | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95848 | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2012-10-04 00:00:00 | |
Bug Depends on: | |||
Bug Blocks: | 24639, 89976 |
Description
Christopher Yeleighton
2011-07-15 06:16:27 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' (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); } (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 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. (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; 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. *** Bug 42561 has been marked as a duplicate of this bug. *** GCC 11 (and prior) diagnose both functions in comment #0, I suspect as a result of r156156: pr49754.c: In function ‘foo’: pr49754.c:2:38: warning: ‘x’ is used uninitialized [-Wuninitialized] 2 | struct i foo () { struct i x; return x; } | ^ pr49754.c:2:28: note: ‘x’ declared here 2 | struct i foo () { struct i x; return x; } | ^ pr49754.c: In function ‘bar’: pr49754.c:3:28: warning: ‘y’ is used uninitialized [-Wuninitialized] 3 | int bar () { int y; return +y; } | ^~ Returning larger aggregates started to be diagnosed in r245840. Passing structs to other functions by value still isn't diagnosed. It used to be, but it stopped sometime between r143699 and r143725. See pr95848 that tracks the problem with pass-by-value. |