Patchwork Fix ctor_for_folding related expansion ICE (PR middle-end/58344)

login
register
mail settings
Submitter Jakub Jelinek
Date Jan. 16, 2014, 7:11 p.m.
Message ID <20140116191133.GW892@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/311827/
State New
Headers show

Comments

Jakub Jelinek - Jan. 16, 2014, 7:11 p.m.
Hi!

Before r200211 expand_expr_real_1 (and other places) used
const_value_known_p which just returned a bool whether the DECL_INITIAL
is usable, but now it has 3 possible return values, error_mark_node
for unusable initial, NULL_TREE for no DECL_INITIAL, but const var
(so, assuming zero initialization) and some other tree otherwise,
while the new error_mark_node/NULL_TREE cases were both rejected
previously.  Because of that we can end up with NULL init now and
crash on it.

The following patch handles this case as zero initialization.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2014-01-16  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/58344
	* expr.c (expand_expr_real_1): Handle init == NULL_TREE.

	* gcc.c-torture/compile/pr58344.c: New test.


	Jakub
Richard Guenther - Jan. 16, 2014, 7:53 p.m.
Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!
>
>Before r200211 expand_expr_real_1 (and other places) used
>const_value_known_p which just returned a bool whether the DECL_INITIAL
>is usable, but now it has 3 possible return values, error_mark_node
>for unusable initial, NULL_TREE for no DECL_INITIAL, but const var
>(so, assuming zero initialization) and some other tree otherwise,
>while the new error_mark_node/NULL_TREE cases were both rejected
>previously.  Because of that we can end up with NULL init now and
>crash on it.
>
>The following patch handles this case as zero initialization.
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

>2014-01-16  Jakub Jelinek  <jakub@redhat.com>
>
>	PR middle-end/58344
>	* expr.c (expand_expr_real_1): Handle init == NULL_TREE.
>
>	* gcc.c-torture/compile/pr58344.c: New test.
>
>--- gcc/expr.c.jj	2014-01-08 19:37:33.000000000 +0100
>+++ gcc/expr.c	2014-01-16 15:08:10.451913525 +0100
>@@ -9832,7 +9832,25 @@ expand_expr_real_1 (tree exp, rtx target
> 		     || TREE_CODE (array) == CONST_DECL)
> 		 && (init = ctor_for_folding (array)) != error_mark_node)
> 	  {
>-	    if (TREE_CODE (init) == CONSTRUCTOR)
>+	    if (init == NULL_TREE)
>+	      {
>+		tree value = build_zero_cst (type);
>+		if (TREE_CODE (value) == CONSTRUCTOR)
>+		  {
>+		    /* If VALUE is a CONSTRUCTOR, this optimization is only
>+		       useful if this doesn't store the CONSTRUCTOR into
>+		       memory.  If it does, it is more efficient to just
>+		       load the data from the array directly.  */
>+		    rtx ret = expand_constructor (value, target,
>+						  modifier, true);
>+		    if (ret == NULL_RTX)
>+		      value = NULL_TREE;
>+		  }
>+
>+		if (value)
>+		  return expand_expr (value, target, tmode, modifier);
>+	      }
>+	    else if (TREE_CODE (init) == CONSTRUCTOR)
> 	      {
> 		unsigned HOST_WIDE_INT ix;
> 		tree field, value;
>--- gcc/testsuite/gcc.c-torture/compile/pr58344.c.jj	2014-01-16
>15:13:45.875197932 +0100
>+++ gcc/testsuite/gcc.c-torture/compile/pr58344.c	2014-01-16
>15:13:07.000000000 +0100
>@@ -0,0 +1,12 @@
>+/* PR middle-end/58344 */
>+/* { dg-do compile } */
>+
>+struct U {};
>+static struct U a[1];
>+extern void bar (struct U);
>+
>+void
>+foo (void)
>+{
>+  bar (a[0]);
>+}
>
>	Jakub

Patch

--- gcc/expr.c.jj	2014-01-08 19:37:33.000000000 +0100
+++ gcc/expr.c	2014-01-16 15:08:10.451913525 +0100
@@ -9832,7 +9832,25 @@  expand_expr_real_1 (tree exp, rtx target
 		     || TREE_CODE (array) == CONST_DECL)
 		 && (init = ctor_for_folding (array)) != error_mark_node)
 	  {
-	    if (TREE_CODE (init) == CONSTRUCTOR)
+	    if (init == NULL_TREE)
+	      {
+		tree value = build_zero_cst (type);
+		if (TREE_CODE (value) == CONSTRUCTOR)
+		  {
+		    /* If VALUE is a CONSTRUCTOR, this optimization is only
+		       useful if this doesn't store the CONSTRUCTOR into
+		       memory.  If it does, it is more efficient to just
+		       load the data from the array directly.  */
+		    rtx ret = expand_constructor (value, target,
+						  modifier, true);
+		    if (ret == NULL_RTX)
+		      value = NULL_TREE;
+		  }
+
+		if (value)
+		  return expand_expr (value, target, tmode, modifier);
+	      }
+	    else if (TREE_CODE (init) == CONSTRUCTOR)
 	      {
 		unsigned HOST_WIDE_INT ix;
 		tree field, value;
--- gcc/testsuite/gcc.c-torture/compile/pr58344.c.jj	2014-01-16 15:13:45.875197932 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr58344.c	2014-01-16 15:13:07.000000000 +0100
@@ -0,0 +1,12 @@ 
+/* PR middle-end/58344 */
+/* { dg-do compile } */
+
+struct U {};
+static struct U a[1];
+extern void bar (struct U);
+
+void
+foo (void)
+{
+  bar (a[0]);
+}