diff mbox series

Fix decode_field_reference ICE (PR middle-end/89091)

Message ID 20190220222904.GP2135@tucnak
State New
Headers show
Series Fix decode_field_reference ICE (PR middle-end/89091) | expand

Commit Message

Jakub Jelinek Feb. 20, 2019, 10:29 p.m. UTC
Hi!

The following testcase ICEs, because we have *pbitsize 65 and
lang_hooks.types.type_for_size returns NULL for that.  The following patch
punts in that case, but makes sure we punt before overwriting *exp_, because
the caller uses it regardless of whether decode_field_reference returns NULL
or not.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

David has proposed to also change c_common_type_for_size to handle the 65 to
127 bit bitsizes, but that looks too risky for me for GCC 9, although if you
think it can go in now, David has a patch for that.

2019-02-20  Jakub Jelinek  <jakub@redhat.com>
	    David Malcolm  <dmalcolm@redhat.com>

	PR middle-end/89091
	* fold-const.c (decode_field_reference): Return NULL_TREE if
	lang_hooks.types.type_for_size returns NULL.  Check it before
	overwriting *exp_.  Use return NULL_TREE instead of return 0.

	* gcc.dg/torture/pr89091.c: New test.


	Jakub

Comments

Jeff Law Feb. 20, 2019, 10:55 p.m. UTC | #1
On 2/20/19 3:29 PM, Jakub Jelinek wrote:
> Hi!
> 
> The following testcase ICEs, because we have *pbitsize 65 and
> lang_hooks.types.type_for_size returns NULL for that.  The following patch
> punts in that case, but makes sure we punt before overwriting *exp_, because
> the caller uses it regardless of whether decode_field_reference returns NULL
> or not.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> David has proposed to also change c_common_type_for_size to handle the 65 to
> 127 bit bitsizes, but that looks too risky for me for GCC 9, although if you
> think it can go in now, David has a patch for that.
> 
> 2019-02-20  Jakub Jelinek  <jakub@redhat.com>
> 	    David Malcolm  <dmalcolm@redhat.com>
> 
> 	PR middle-end/89091
> 	* fold-const.c (decode_field_reference): Return NULL_TREE if
> 	lang_hooks.types.type_for_size returns NULL.  Check it before
> 	overwriting *exp_.  Use return NULL_TREE instead of return 0.
> 
> 	* gcc.dg/torture/pr89091.c: New test.
OK.  I'd wait on handling the additional bitsizes,  it doesn't seem like
it deserves gcc-9 consideration to me.

jeff
diff mbox series

Patch

--- gcc/fold-const.c.jj	2019-02-14 10:24:16.300632811 +0100
+++ gcc/fold-const.c	2019-02-20 15:52:35.476932131 +0100
@@ -4280,7 +4280,7 @@  decode_field_reference (location_t loc,
      There are problems with FP fields since the type_for_size call
      below can fail for, e.g., XFmode.  */
   if (! INTEGRAL_TYPE_P (TREE_TYPE (exp)))
-    return 0;
+    return NULL_TREE;
 
   /* We are interested in the bare arrangement of bits, so strip everything
      that doesn't affect the machine mode.  However, record the type of the
@@ -4296,7 +4296,7 @@  decode_field_reference (location_t loc,
       exp = TREE_OPERAND (exp, 0);
       STRIP_NOPS (exp); STRIP_NOPS (and_mask);
       if (TREE_CODE (and_mask) != INTEGER_CST)
-	return 0;
+	return NULL_TREE;
     }
 
   poly_int64 poly_bitsize, poly_bitpos;
@@ -4312,7 +4312,11 @@  decode_field_reference (location_t loc,
       || (! AGGREGATE_TYPE_P (TREE_TYPE (inner))
 	  && compare_tree_int (TYPE_SIZE (TREE_TYPE (inner)),
 			       *pbitpos + *pbitsize) < 0))
-    return 0;
+    return NULL_TREE;
+
+  unsigned_type = lang_hooks.types.type_for_size (*pbitsize, 1);
+  if (unsigned_type == NULL_TREE)
+    return NULL_TREE;
 
   *exp_ = exp;
 
@@ -4323,7 +4327,6 @@  decode_field_reference (location_t loc,
     *punsignedp = TYPE_UNSIGNED (outer_type);
 
   /* Compute the mask to access the bitfield.  */
-  unsigned_type = lang_hooks.types.type_for_size (*pbitsize, 1);
   precision = TYPE_PRECISION (unsigned_type);
 
   mask = build_int_cst_type (unsigned_type, -1);
--- gcc/testsuite/gcc.dg/torture/pr89091.c.jj	2019-02-20 15:55:54.604694453 +0100
+++ gcc/testsuite/gcc.dg/torture/pr89091.c	2019-02-20 15:55:18.186294196 +0100
@@ -0,0 +1,10 @@ 
+/* PR middle-end/89091 */
+/* { dg-do compile { target int128 } } */
+
+struct S { unsigned __int128 s : 65; };
+
+int
+foo (struct S *x, int y)
+{
+  return y && x->s;
+}