diff mbox

Fix 78550 ICE with bit-field initialization

Message ID 470fb13a-9eae-bca1-d6a8-25bd55a35ab2@acm.org
State New
Headers show

Commit Message

Nathan Sidwell Dec. 8, 2016, 4:38 p.m. UTC
This patch fixes 78550, where we ICE in varasm as we discover a 
code-generating NOP_EXPR of an INTEGER_CST.  output_constructor 
(varasm.c) has a STRIP_NOPs, but that leaves the NOP alone, as it is 
truncating a regular QI mode operand to a 1 bit type.

That tree is generated in convert.c:
       /* If TYPE is an enumeral type or a type with a precision less
	 than the number of bits in its mode, do the conversion to the
	 type corresponding to its mode, then do a nop conversion
	 to TYPE.  */
....
	  return fold_build1_loc (dofold, loc, NOP_EXPR, type, ...);
	}
Fixed by changing it to maybe_fold_build1_loc.  Surrounding code uses 
that function.

ok?

nathan
-- 
Nathan Sidwell

Comments

Richard Biener Dec. 9, 2016, 10:02 a.m. UTC | #1
On Thu, Dec 8, 2016 at 5:38 PM, Nathan Sidwell <nathan@acm.org> wrote:
> This patch fixes 78550, where we ICE in varasm as we discover a

> code-generating NOP_EXPR of an INTEGER_CST.  output_constructor (varasm.c)

> has a STRIP_NOPs, but that leaves the NOP alone, as it is truncating a

> regular QI mode operand to a 1 bit type.

>

> That tree is generated in convert.c:

>       /* If TYPE is an enumeral type or a type with a precision less

>          than the number of bits in its mode, do the conversion to the

>          type corresponding to its mode, then do a nop conversion

>          to TYPE.  */

> ....

>           return fold_build1_loc (dofold, loc, NOP_EXPR, type, ...);

>         }

> Fixed by changing it to maybe_fold_build1_loc.  Surrounding code uses that

> function.

>

> ok?


Ok.

Thanks,
Richard.

> nathan

> --

> Nathan Sidwell
diff mbox

Patch

2016-12-08  Nathan Sidwell  <nathan@acm.org>

	PR c++/78550
	* convert.c (convert_to_integer_1): Maybe fold conversions to
	integral types with fewer bits than its mode.

	testsuite/
	PR c++/78550
	* g++.dg/cpp1y/pr78550.C: New.

Index: convert.c
===================================================================
--- convert.c	(revision 243438)
+++ convert.c	(working copy)
@@ -646,10 +646,11 @@  convert_to_integer_1 (tree type, tree ex
 	 to TYPE.  */
       else if (TREE_CODE (type) == ENUMERAL_TYPE
 	       || outprec != GET_MODE_PRECISION (TYPE_MODE (type)))
-	return build1 (NOP_EXPR, type,
-		       convert (lang_hooks.types.type_for_mode
-				(TYPE_MODE (type), TYPE_UNSIGNED (type)),
-				expr));
+	{
+	  expr = convert (lang_hooks.types.type_for_mode
+			  (TYPE_MODE (type), TYPE_UNSIGNED (type)), expr);
+	  return maybe_fold_build1_loc (dofold, loc, NOP_EXPR, type, expr);
+	}
 
       /* Here detect when we can distribute the truncation down past some
 	 arithmetic.  For example, if adding two longs and converting to an
Index: testsuite/g++.dg/cpp1y/pr78550.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr78550.C	(revision 0)
+++ testsuite/g++.dg/cpp1y/pr78550.C	(working copy)
@@ -0,0 +1,22 @@ 
+// { dg-do compile { target c++14 } }
+
+// PR 78550 ICE with initializer_list and bitfield member
+
+namespace std
+{
+  template <class T>
+  struct initializer_list
+    {
+      const T *a;
+      __SIZE_TYPE__ b;
+      constexpr initializer_list (const T *x, __SIZE_TYPE__ y) : a(x), b(y) { }
+    };
+}
+template <typename T>
+struct A {
+  A (std::initializer_list<T>);
+};
+struct B {
+  int k : 1;
+};
+A<B> a{{0}};