Hi! The testcase shows that when expanding ARRAY_REF from a const static var with initializer that contains COMPOUND_LITERAL_EXPR, we can try to expand COMPOUND_LITERAL_EXPR even when modifier is not EXPAND_INITIALIZER (it is EXPAND_SUM in that testcase, but could be many others). While gimplification should get rid of all the compound literal exprs for automatic compound literals, COMPOUND_LITERAL_EXPR for static compound literals can survive in the initializers, thus this patch handles them always.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2014-11-26 Jakub Jelinek <ja...@redhat.com> PR middle-end/64067 * expr.c (expand_expr_addr_expr_1) <case COMPOUND_LITERAL_EXPR>: Handle it by returning address of COMPOUND_LITERAL_EXPR_DECL not only if modifier is EXPAND_INITIALIZER, but whenever COMPOUND_LITERAL_EXPR_DECL is non-NULL and TREE_STATIC. * gcc.c-torture/compile/pr64067.c: New test. --- gcc/expr.c.jj 2014-11-18 08:26:45.000000000 +0100 +++ gcc/expr.c 2014-11-26 17:38:52.877675088 +0100 @@ -7677,11 +7677,13 @@ expand_expr_addr_expr_1 (tree exp, rtx t break; case COMPOUND_LITERAL_EXPR: - /* Allow COMPOUND_LITERAL_EXPR in initializers, if e.g. - rtl_for_decl_init is called on DECL_INITIAL with - COMPOUNT_LITERAL_EXPRs in it, they aren't gimplified. */ - if (modifier == EXPAND_INITIALIZER - && COMPOUND_LITERAL_EXPR_DECL (exp)) + /* Allow COMPOUND_LITERAL_EXPR in initializers or coming from + initializers, if e.g. rtl_for_decl_init is called on DECL_INITIAL + with COMPOUND_LITERAL_EXPRs in it, or ARRAY_REF on a const static + array with address of COMPOUND_LITERAL_EXPR in DECL_INITIAL; + the initializers aren't gimplified. */ + if (COMPOUND_LITERAL_EXPR_DECL (exp) + && TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (exp))) return expand_expr_addr_expr_1 (COMPOUND_LITERAL_EXPR_DECL (exp), target, tmode, modifier, as); /* FALLTHRU */ --- gcc/testsuite/gcc.c-torture/compile/pr64067.c.jj 2014-11-26 17:37:37.835865797 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr64067.c 2014-11-26 17:37:02.000000000 +0100 @@ -0,0 +1,10 @@ +/* PR middle-end/64067 */ + +struct S { int s; }; +int *const v[1] = { &((struct S) { .s = 42 }).s }; + +int * +foo (void) +{ + return v[0]; +} Jakub