Consider this code: struct p { short x, y; }; struct s { int i; struct p p; }; struct s f() { struct s s; s.p = (struct p){}; s.i = (s.p.x || s.p.y); return s; } When compiled with gcc -Wall -O -c, it reports: t.c: In function 'f': t.c:14: warning: 's.i' is used uninitialized in this function That's not right. Furthermore, I think the generated assembly might be wrong (this is with -O): f: movl $0, %eax ret The return value should be a full 64 bits (%rax), but only the bottom 32 are initialized (unless this clears the high ones on x86_64 or the calling convention says they are already -- I don't really know).
First this is a very bogus warning. Second this is caused by SRA and BIT_FIELD_REF: D.1509.x = 0; D.1509.y = 0; s.p = D.1509; D.1511_10 = BIT_FIELD_REF <s, 32, 32>; D.1512_12 = D.1511_10 != 0; s.i = D.1512_12; D.1513 = s; The problem is that SRA does not look into seeing if s.i is needed so it does: SR.25_11 = 0; SR.24_26 = 0; s$p$y_27 = SR.24_26; s$p$x_28 = SR.25_11; s.i = s$i_29; s.p.y = s$p$y_27; s.p.x = s$p$x_28; D.1511_10 = BIT_FIELD_REF <s, 32, 32>; D.1512_12 = D.1511_10 != 0; s$i_33 = D.1512_12; s.i = s$i_33; s.p.y = s$p$y_27; s.p.x = s$p$x_28; D.1513 = s; The wrong code part is not really wrong code, just a misunderstanding of what the instruction does: (insn 43 40 49 (set (reg/i:DI 0 ax [ <result> ]) (const_int 0 [0x0])) 81 {*movdi_1_rex64} (insn_list:REG_DEP_TRUE 35 (nil)) (nil)) It sign extends to the full register which means rax is 0 and not just the bottom part. Hmm, even the struct aliasing code does not know either: # VUSE <SFT.3_7>; # VUSE <SFT.4_8>; # VUSE <SFT.5_9>; D.1511_10 = BIT_FIELD_REF <s, 32, 32>;
This is annoying warning; let's fix.
Subject: Bug 24931 Author: rth Date: Mon Nov 21 00:51:39 2005 New Revision: 107271 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=107271 Log: PR 24931 * tree-sra.c (struct sra_elt): Add all_no_warning. (struct sra_walk_fns) <use>: Add use_all argument. (sra_walk_expr): Pass it. (sra_walk_modify_expr): Likewise. (scalarize_ldst): Likewise. (scan_use): Update for new argument. (mark_no_warning): New. (scalarize_use): Use it. Added: trunk/gcc/testsuite/gcc.dg/uninit-14.c Modified: trunk/gcc/ChangeLog trunk/gcc/tree-sra.c
Subject: Bug 24931 Author: rth Date: Mon Nov 21 00:55:57 2005 New Revision: 107272 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=107272 Log: PR 24931 * tree-sra.c (struct sra_elt): Add all_no_warning. (struct sra_walk_fns) <use>: Add use_all argument. (sra_walk_expr): Pass it. (sra_walk_modify_expr): Likewise. (scalarize_ldst): Likewise. (scan_use): Update for new argument. (mark_no_warning): New. (scalarize_use): Use it. Added: branches/gcc-4_1-branch/gcc/testsuite/gcc.dg/uninit-14.c - copied unchanged from r107271, trunk/gcc/testsuite/gcc.dg/uninit-14.c Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/tree-sra.c
Fixed at least on the mainline and 4.1 branch for now.
Fixed in GCC-4.1.0