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
2016-12-08 Nathan Sidwell <nat...@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}};