diff mbox

Fix expansion with COMPOUND_LITERAL_EXPR (PR middle-end/64067)

Message ID 20141126190031.GS1669@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 26, 2014, 7 p.m. UTC
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  <jakub@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.


	Jakub

Comments

Richard Biener Nov. 27, 2014, 10:03 a.m. UTC | #1
On Wed, 26 Nov 2014, Jakub Jelinek wrote:

> 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?

Ok.  (I wonder if the fallthru still makes sense or if we should
hit a gcc_unreachable () for other uses of COMPOUND_LITERAL_EXPR).

Thanks,
Richard.

> 2014-11-26  Jakub Jelinek  <jakub@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
> 
>
Jakub Jelinek Nov. 27, 2014, 10:19 a.m. UTC | #2
On Thu, Nov 27, 2014 at 11:03:20AM +0100, Richard Biener wrote:
> > 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?
> 
> Ok.  (I wonder if the fallthru still makes sense or if we should
> hit a gcc_unreachable () for other uses of COMPOUND_LITERAL_EXPR).

I think the fallthru can't work, because it will hit the gcc_unreachable ();
on unhandled COMPOUND_LITERAL_EXPR in expand_expr_real_*.
So changing the if in the patch into gcc_assert and removing /* FALLTHRU */
might be ok too (and removing == COMPOUND_LITERAL_EXPR from the fallthru
if).

> > 2014-11-26  Jakub Jelinek  <jakub@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 */

	Jakub
diff mbox

Patch

--- 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];
+}