With this testcase, on ARM I see: $ ./cc1plus -quiet -I. -Wuninitialized -O q.C q.C: In constructor ‘B::B()’: q.C:4:7: warning: ‘<anonymous>’ is used uninitialized in this function [-Wuninitialized] A() {} ^ Started with r245840. The C++ ABI for ARM says that cdtors return "this" instead of returning void, so in .original we have <<cleanup_point <<< Unknown tree: expr_stmt *(struct { ._0 e; int i; int j; } &) this = {CLOBBER} >>>>>; { } <D.4688>:; return this; And the last line provokes the warning. class A { public: enum { } e; A() {} int i; int j; }; class B { B(); A a; }; A fn1() { return A(); } B::B() : a(fn1()) {}
Confirmed. The IL we warn about is B::B() (struct B * const this) { struct { ._0 e; int i; int j; } D.4784; <bb 2> [100.00%]: D.4784 ={v} {CLOBBER}; MEM[(struct &)this_2(D)] = D.4784; return this_2(D); and we warn about the MEM[(struct &)this_2(D)] = D.4784; assignment. The warning is clearly correct as the A members are not initialized. Did you reduce a testcase too far?
Created attachment 41150 [details] orig.ii.gz This is the original .ii file.
I believe this is exposed by inlining this_14(D)->http_ver = Http::ProtocolVersion (); [return slot optimization] as D.148385 ={v} {CLOBBER}; MEM[(struct &)this_14(D) + 4] = D.148385; this_14(D)->http_ver.protocol = 1; this_14(D)->http_ver.major = 1; this_14(D)->http_ver.minor = 1; which is AnyP::ProtocolVersion Http::ProtocolVersion() () { <bb 2> [0.00%]: AnyP::ProtocolVersion::ProtocolVersion (&<retval>, 1, 1, 1); return <retval>; inlined into like AnyP::ProtocolVersion Http::ProtocolVersion() () { struct ProtocolVersion * D.148207; <bb 2> [100.00%]: MEM[(struct &)&<retval>] ={v} {CLOBBER}; <retval>.protocol = 1; <retval>.major = 1; <retval>.minor = 1; _7 = &<retval>; return <retval>; not sure how this ends up happening. Smaller testcase appreciated ;) The above is from 029t.einline vs. 028t.inline_param1.
So it happens when inlining MEM[(struct &)&<retval>] ={v} {CLOBBER}; and substituting &this_14(D)->http_ver for the address. Then we trigger id->regimplify = true; but in the end we simplify it to MEM[(struct &)this_14(D) + 4] ={v} {CLOBBER}; and gimple_regimplify_operands wrecks this via else if (i == 2 && is_gimple_assign (stmt) && num_ops == 2 && get_gimple_rhs_class (gimple_expr_code (stmt)) == GIMPLE_SINGLE_RHS) gimplify_expr (&op, &pre, NULL, rhs_predicate_for (gimple_assign_lhs (stmt)), fb_rvalue); and {CLOBBER} is not is_gimple_mem_rhs_or_call. Testing Index: gcc/gimplify.c =================================================================== --- gcc/gimplify.c (revision 246757) +++ gcc/gimplify.c (working copy) @@ -493,7 +493,9 @@ is_gimple_mem_rhs_or_call (tree t) if (is_gimple_reg_type (TREE_TYPE (t))) return is_gimple_val (t); else - return (is_gimple_val (t) || is_gimple_lvalue (t) + return (is_gimple_val (t) + || is_gimple_lvalue (t) + || TREE_CLOBBER_P (t) || TREE_CODE (t) == CALL_EXPR); }
Fixed.
Author: rguenth Date: Mon Apr 10 08:58:02 2017 New Revision: 246800 URL: https://gcc.gnu.org/viewcvs?rev=246800&root=gcc&view=rev Log: 2017-04-10 Richard Biener <rguenther@suse.de> PR middle-end/80344 * gimplify.c (is_gimple_mem_rhs_or_call): Allow CLOBBERs. Modified: trunk/gcc/ChangeLog trunk/gcc/gimplify.c