diff mbox

fix cross build

Message ID 4FB928DA.8090806@acm.org
State New
Headers show

Commit Message

Nathan Sidwell May 20, 2012, 5:24 p.m. UTC
In building a ppc cross compiler using a freshly built native compiler, I 
encountered an ICE in iterative_hash_expr compiling c-lex.c.  I extracted the 
attached testcase, showing the problem is with statement expressions. 
Investigation showed I_H_E seeing BLOCK and BIND_EXPR nodes, which is was 
unprepared for.  These two nodes are never considered equal by operand_equal_p, 
so we don't need to look into them further to refine the hash.

I'm not sure why a native i686-pc-linux-gnu bootstrap doesn't encounter this 
problem.

The attached patch resolves the ICE.  built and tested on i686-pc-linux-gnu, ok?

nathan

Comments

Richard Biener May 21, 2012, 10:03 a.m. UTC | #1
On Sun, May 20, 2012 at 7:24 PM, Nathan Sidwell <nathan@acm.org> wrote:
> In building a ppc cross compiler using a freshly built native compiler, I
> encountered an ICE in iterative_hash_expr compiling c-lex.c.  I extracted
> the attached testcase, showing the problem is with statement expressions.
> Investigation showed I_H_E seeing BLOCK and BIND_EXPR nodes, which is was
> unprepared for.  These two nodes are never considered equal by
> operand_equal_p, so we don't need to look into them further to refine the
> hash.
>
> I'm not sure why a native i686-pc-linux-gnu bootstrap doesn't encounter this
> problem.
>
> The attached patch resolves the ICE.  built and tested on i686-pc-linux-gnu,
> ok?

Hmm - I think this papers over the issue that the CONSTRUCTOR is not
properly gimplified - it still contains a TARGET_EXPR which is not valid GIMPLE.
Why is that TARGET_EXPR not gimplified?

Richard.

> nathan
Nathan Sidwell May 22, 2012, 1:24 p.m. UTC | #2
On 05/21/12 11:03, Richard Guenther wrote:

> Hmm - I think this papers over the issue that the CONSTRUCTOR is not
> properly gimplified - it still contains a TARGET_EXPR which is not valid GIMPLE.
> Why is that TARGET_EXPR not gimplified?

As far as I can make out, it just doesn't look inside the constructor.

0  gimplify_expr (expr_p=0xb7e90394, pre_p=0xbfffe514, post_p=0xbfffd08c,
     gimple_test_f=0x84b0a80 <is_gimple_min_lval(tree_node*)>, fallback=3) at 
../../src/gcc/gimplify.c:7356
#1  0x084f5882 in gimplify_compound_lval (expr_p=0xb7e9cb94, pre_p=0xbfffe514, 
post_p=0xbfffd08c, fallback=1)
     at ../../src/gcc/gimplify.c:2259
#2  0x08519878 in gimplify_expr (expr_p=0xb7e9cb94, pre_p=0xbfffe514, 
post_p=0xbfffd08c,
     gimple_test_f=0x84eaf9f <is_gimple_reg_rhs_or_call(tree)>, fallback=1) at 
../../src/gcc/gimplify.c:7081
#3  0x085087f7 in gimplify_modify_expr (expr_p=0xbfffd6d0, pre_p=0xbfffe514, 
post_p=0xbfffd08c, want_value=false)
     at ../../src/gcc/gimplify.c:4843

The switch case at that stack frame is for CONSTRUCTORs.  It has the comment:
/* Don't reduce this in place; let gimplify_init_constructor work its
	     magic.  Buf if we're just elaborating this for side effects, just
	     gimplify any element that has side-effects.  */

But we never enter G_I_C before the ICE.

On the second time we get here, fallback has the value 1 at that point 
(fb_rvalue), so neither if condition is satisified, and we end up at
	    ret = GS_ALL_DONE;
we then proceed down to enter:
  else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
     {
       /* An rvalue will do.  Assign the gimplified expression into a
	 new temporary TMP and replace the original expression with
	 TMP.  First, make sure that the expression has a type so that
	 it can be assigned into a temporary.  */
       gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
       *expr_p = get_formal_tmp_var (*expr_p, pre_p);
     }

and ICE inside GFTV when it attempts to generate the hash.

AFAICT, changing the test case to:
   char *str = ((union {const char * _q; char * _nq;})
	       ((const char *)((num_string)
			       ->string.str)))._nq;
(i.e. removing the stmt-expr) results in the same logical flow as above, but 
there's no TARGET_EXPR inside the constructor.

I'm not sure how it's supposed to work, so I'm a little lost.
diff mbox

Patch

2012-05-20  Nathan Sidwell  <nathan@acm.org>

	* tree.c (iterative_hash_expr): Add BLOCK and BIND_EXPR cases.

	* gcc.dg/stmt-expr-4.c: New.

Index: tree.c
===================================================================
--- tree.c	(revision 187628)
+++ tree.c	(working copy)
@@ -6998,6 +6998,11 @@  iterative_hash_expr (const_tree t, hashv
 	  }
 	return val;
       }
+    case BLOCK:
+    case BIND_EXPR:
+      /* These are never equal operands. The contain nodes we're not
+	 prepared for, so stop now.  */
+      return val;
     case MEM_REF:
       {
 	/* The type of the second operand is relevant, except for
Index: testsuite/gcc.dg/stmt-expr-4.c
===================================================================
--- testsuite/gcc.dg/stmt-expr-4.c	(revision 0)
+++ testsuite/gcc.dg/stmt-expr-4.c	(revision 0)
@@ -0,0 +1,22 @@ 
+
+/* { dg-options "-O2 -std=gnu99" } */
+/* Internal compiler error in iterative_hash_expr */
+
+struct tree_string
+{
+  char str[1];
+};
+
+union tree_node
+{
+  struct tree_string string;
+};
+
+char *Foo (union tree_node * num_string)
+{
+  char *str = ((union {const char * _q; char * _nq;})
+	       ((const char *)(({ __typeof (num_string) const __t
+				     = num_string;  __t; })
+			       ->string.str)))._nq;
+  return str;
+}