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

Reply via email to