aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-09-23 19:38:29 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2016-09-23 19:38:29 +0200
commitd664d76d00b19a61afec13425a9421a62e437505 (patch)
tree0dab028d22f5c23310e12547c146e8c3c2412cbb
parent24cae8cb9adca74ad4038d2bb55380e486aed8c0 (diff)
downloadgcc-d664d76d00b19a61afec13425a9421a62e437505.zip
gcc-d664d76d00b19a61afec13425a9421a62e437505.tar.gz
gcc-d664d76d00b19a61afec13425a9421a62e437505.tar.bz2
Implement P0138R2, C++17 construction rules for enum class values
Implement P0138R2, C++17 construction rules for enum class values * cp-tree.h (is_direct_enum_init): Declare. * decl.c (is_direct_enum_init): New function. (reshape_init): Use it. * typeck.c (convert_for_assignment): Likewise. * g++.dg/cpp1z/direct-enum-init1.C: New test. From-SVN: r240449
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c27
-rw-r--r--gcc/cp/typeck.c11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C237
6 files changed, 287 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7109684..a3430bf 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2016-09-23 Jakub Jelinek <jakub@redhat.com>
+ Implement P0138R2, C++17 construction rules for enum class values
+ * cp-tree.h (is_direct_enum_init): Declare.
+ * decl.c (is_direct_enum_init): New function.
+ (reshape_init): Use it.
+ * typeck.c (convert_for_assignment): Likewise.
+
* Make-lang.in (check-c++1z): Pass RUNTESTFLAGS down to
make check-g++.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f403340..c7a38fa 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5829,6 +5829,7 @@ extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
extern void warn_extern_redeclared_static (tree, tree);
extern tree cxx_comdat_group (tree);
extern bool cp_missing_noreturn_ok_p (tree);
+extern bool is_direct_enum_init (tree, tree);
extern void initialize_artificial_var (tree, vec<constructor_elt, va_gc> *);
extern tree check_var_type (tree, tree);
extern tree reshape_init (tree, tree, tsubst_flags_t);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 24f71ce..3dfa042 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5581,6 +5581,22 @@ next_initializable_field (tree field)
return field;
}
+/* Return true for [dcl.init.list] direct-list-initialization from
+ single element of enumeration with a fixed underlying type. */
+
+bool
+is_direct_enum_init (tree type, tree init)
+{
+ if (cxx_dialect >= cxx1z
+ && TREE_CODE (type) == ENUMERAL_TYPE
+ && ENUM_FIXED_UNDERLYING_TYPE_P (type)
+ && TREE_CODE (init) == CONSTRUCTOR
+ && CONSTRUCTOR_IS_DIRECT_INIT (init)
+ && CONSTRUCTOR_NELTS (init) == 1)
+ return true;
+ return false;
+}
+
/* Subroutine of reshape_init_array and reshape_init_vector, which does
the actual work. ELT_TYPE is the element type of the array. MAX_INDEX is an
INTEGER_CST representing the size of the array minus one (the maximum index),
@@ -6026,6 +6042,17 @@ reshape_init (tree type, tree init, tsubst_flags_t complain)
if (vec_safe_is_empty (v))
return init;
+ /* Handle [dcl.init.list] direct-list-initialization from
+ single element of enumeration with a fixed underlying type. */
+ if (is_direct_enum_init (type, init))
+ {
+ tree elt = CONSTRUCTOR_ELT (init, 0)->value;
+ if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain))
+ return cp_build_c_cast (type, elt, tf_warning_or_error);
+ else
+ return error_mark_node;
+ }
+
/* Recurse on this CONSTRUCTOR. */
d.cur = &(*v)[0];
d.end = d.cur + v->length ();
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index c53a85a..b2af615 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8266,6 +8266,17 @@ convert_for_assignment (tree type, tree rhs,
if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
rhs = TREE_OPERAND (rhs, 0);
+ /* Handle [dcl.init.list] direct-list-initialization from
+ single element of enumeration with a fixed underlying type. */
+ if (is_direct_enum_init (type, rhs))
+ {
+ tree elt = CONSTRUCTOR_ELT (rhs, 0)->value;
+ if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain))
+ rhs = cp_build_c_cast (type, elt, complain);
+ else
+ rhs = error_mark_node;
+ }
+
rhstype = TREE_TYPE (rhs);
coder = TREE_CODE (rhstype);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7a853dc..080e556 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-09-23 Jakub Jelinek <jakub@redhat.com>
+
+ Implement P0138R2, C++17 construction rules for enum class values
+ * g++.dg/cpp1z/direct-enum-init1.C: New test.
+
2016-09-23 David Malcolm <dmalcolm@redhat.com>
PR preprocessor/77672
diff --git a/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C b/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C
new file mode 100644
index 0000000..b473ed5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C
@@ -0,0 +1,237 @@
+// P0138R2 - direct-list-initialization of enums
+// { dg-do compile { target c++11 } }
+
+enum A { G = 26 };
+enum B : short {};
+enum class C {};
+enum struct D : long {};
+enum class E : unsigned char { e = 7 };
+struct S { operator C () { return C (s); } int s; } s;
+struct T { operator long () { return t; } long t; } t;
+struct V { E v; };
+long l;
+long long ll;
+short c;
+void bar (E);
+
+void
+foo ()
+{
+ A a1 { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" }
+ B b1 { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } }
+ C c1 { s };
+ D d1 { D(t) }; // { dg-error "invalid cast from type 'T' to type 'D'" }
+ D d2 { t }; // { dg-error "cannot convert 'T' to 'D' in initialization" "" { target c++14_down } }
+ // { dg-error "invalid cast from type 'T' to type 'D'" "" { target c++1z } .-1 }
+ D d3 { 9 }; // { dg-error "cannot convert 'int' to 'D' in initialization" "" { target c++14_down } }
+ D d4 { l }; // { dg-error "cannot convert 'long int' to 'D' in initialization" "" { target c++14_down } }
+ D d5 { D(l) };
+ D d6 { G }; // { dg-error "cannot convert 'A' to 'D' in initialization" "" { target c++14_down } }
+ E e1 { 5 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ E e2 { -1 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '-1' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ E e3 { 5.0 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ E e4 { 5.2 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.\[0-9]*e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ B b2 = { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" }
+ C c2 = { C { 8 } }; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } }
+
+ D *d7 = new D { 9 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target c++14_down } }
+ E *e5 = new E { -4 }; // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ bar ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E' for argument" }
+ bar (E { 9 }); // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ V v1 = { { 11 } }; // { dg-error "braces around scalar initializer for type 'E'" }
+ V v2 = { E { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ V v3 = { E { 5.0 } }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ V v4 = { 13 }; // { dg-error "cannot convert 'int' to 'E' in initialization" }
+ if (B b3 { 5 }) // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } }
+ ;
+ if (B b4 { 4.0 }) // { dg-error "cannot convert 'double' to 'B' in initialization" "" { target c++14_down } }
+ ; // { dg-error "narrowing conversion of '4.0e.0' from 'double' to 'short int' inside" "" { target c++1z } .-1 }
+ C c3 { 8L }; // { dg-error "cannot convert 'long int' to 'C' in initialization" "" { target c++14_down } }
+ B b4 {short (c + 5)}; // { dg-error "invalid conversion from 'short int' to 'B'" "" { target c++14_down } }
+ B b5 {c + 5}; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of \[^\n\r]* from 'int' to 'short int' inside" "" { target c++1z } .-1 }
+ C c4 { ll }; // { dg-error "cannot convert 'long long int' to 'C' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of 'll' from 'long long int' to 'int' inside" "" { target c++1z } .-1 }
+ C c5 {short (c + 5)}; // { dg-error "cannot convert 'short int' to 'C' in initialization" "" { target c++14_down } }
+ C c6 {c + 5}; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } }
+}
+
+struct U
+{
+ U () : e { 5 } {} // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } }
+ U (int) : e { 5.0 } {}// { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ U (float) : e({ 6 }) {}// { dg-error "list-initializer for non-class type must not be parenthesized" }
+ // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target *-*-* } .-1 }
+ E e;
+};
+
+struct W
+{
+ A a { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" }
+ B b { 6 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } }
+ C c { 3.0f }; // { dg-error "cannot convert \[^\n\r]* to 'C' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '3.0e.0f' from 'float' to 'int' inside" "" { target c++1z } .-1 }
+ D d = { 7 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" }
+};
+
+template <int N>
+void
+foo2 ()
+{
+ A a1 { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" }
+ B b1 { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } }
+ C c1 { s };
+ D d1 { D(t) }; // { dg-error "invalid cast from type 'T' to type 'D'" }
+ D d2 { t }; // { dg-error "cannot convert 'T' to 'D' in initialization" "" { target c++14_down } }
+ // { dg-error "invalid cast from type 'T' to type 'D'" "" { target c++1z } .-1 }
+ D d3 { 9 }; // { dg-error "cannot convert 'int' to 'D' in initialization" "" { target c++14_down } }
+ D d4 { l }; // { dg-error "cannot convert 'long int' to 'D' in initialization" "" { target c++14_down } }
+ D d5 { D(l) };
+ D d6 { G }; // { dg-error "cannot convert 'A' to 'D' in initialization" "" { target c++14_down } }
+ E e1 { 5 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ E e2 { -1 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '-1' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ E e3 { 5.0 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ E e4 { 5.2 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.\[0-9]*e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ B b2 = { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" }
+ C c2 = { C { 8 } }; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } }
+ D *d7 = new D { 9 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target c++14_down } }
+ E *e5 = new E { -4 }; // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ bar ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E' for argument" }
+ bar (E { 9 }); // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ V v1 = { { 11 } }; // { dg-error "braces around scalar initializer for type 'E'" }
+ V v2 = { E { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ V v3 = { E { 5.0 } }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ V v4 = { 13 }; // { dg-error "cannot convert 'int' to 'E' in initialization" }
+ if (B b3 { 5 }) // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } }
+ ;
+ if (B b4 { 4.0 }) // { dg-error "cannot convert 'double' to 'B' in initialization" "" { target c++14_down } }
+ ; // { dg-error "narrowing conversion of '4.0e.0' from 'double' to 'short int' inside" "" { target c++1z } .-1 }
+ C c3 { 8L }; // { dg-error "cannot convert 'long int' to 'C' in initialization" "" { target c++14_down } }
+ B b4 {short (c + 5)}; // { dg-error "invalid conversion from 'short int' to 'B'" "" { target c++14_down } }
+ B b5 {c + 5}; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of \[^\n\r]* from 'int' to 'short int' inside" "" { target c++1z } .-1 }
+ C c4 { ll }; // { dg-error "cannot convert 'long long int' to 'C' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of 'll' from 'long long int' to 'int' inside" "" { target c++1z } .-1 }
+ C c5 {short (c + 5)}; // { dg-error "cannot convert 'short int' to 'C' in initialization" "" { target c++14_down } }
+ C c6 {c + 5}; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } }
+}
+
+template <int N>
+struct U2
+{
+ U2 () : e { 5 } {} // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } }
+ U2 (int) : e { 5.0 } {}// { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ U2 (float) : e({ 6 }) {}
+ E e;
+};
+
+template <int N>
+struct W2
+{
+ A a { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" "" { target *-*-* } .-2 }
+ B b { 6 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } .-3 }
+ C c { 3.0f }; // { dg-error "cannot convert \[^\n\r]* to 'C' in initialization" "" { target c++14_down } .-4 }
+ // { dg-error "narrowing conversion of '3.0e.0f' from 'float' to 'int' inside" "" { target c++1z } .-5 }
+ D d = { 7 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target *-*-* } .-6 }
+};
+
+template <typename H, typename I, typename J, typename K, typename L, typename M>
+void
+foo3 ()
+{
+ void bar3 (L);
+ H a1 { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" }
+ I b1 { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } }
+ J c1 { s };
+ K d1 { K(t) }; // { dg-error "invalid cast from type 'T' to type 'D'" }
+ K d2 { t }; // { dg-error "cannot convert 'T' to 'D' in initialization" "" { target c++14_down } }
+ // { dg-error "invalid cast from type 'T' to type 'D'" "" { target c++1z } .-1 }
+ K d3 { 9 }; // { dg-error "cannot convert 'int' to 'D' in initialization" "" { target c++14_down } }
+ K d4 { l }; // { dg-error "cannot convert 'long int' to 'D' in initialization" "" { target c++14_down } }
+ K d5 { K(l) };
+ K d6 { G }; // { dg-error "cannot convert 'A' to 'D' in initialization" "" { target c++14_down } }
+ L e1 { 5 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ L e2 { -1 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '-1' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ L e3 { 5.0 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ L e4 { 5.2 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.\[0-9]*e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ I b2 = { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" }
+ J c2 = { J { 8 } }; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } }
+ K *d7 = new K { 9 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target c++14_down } }
+ L *e5 = new L { -4 }; // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ bar3 ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E' for argument" }
+ bar3 (E { 9 }); // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ M v1 = { { 11 } }; // { dg-error "braces around scalar initializer for type 'E'" }
+ M v2 = { L { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
+ M v3 = { L { 5.0 } }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ M v4 = { 13 }; // { dg-error "cannot convert 'int' to 'E' in initialization" }
+ if (I b3 { 5 }) // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } }
+ ;
+ if (I b4 { 4.0 }) // { dg-error "cannot convert 'double' to 'B' in initialization" "" { target c++14_down } }
+ ; // { dg-error "narrowing conversion of '4.0e.0' from 'double' to 'short int' inside" "" { target c++1z } .-1 }
+ J c3 { 8L }; // { dg-error "cannot convert 'long int' to 'C' in initialization" "" { target c++14_down } }
+ I b4 {short (c + 5)}; // { dg-error "invalid conversion from 'short int' to 'B'" "" { target c++14_down } }
+ I b5 {c + 5}; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of \[^\n\r]* from 'int' to 'short int' inside" "" { target c++1z } .-1 }
+ J c4 { ll }; // { dg-error "cannot convert 'long long int' to 'C' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of 'll' from 'long long int' to 'int' inside" "" { target c++1z } .-1 }
+ J c5 {short (c + 5)}; // { dg-error "cannot convert 'short int' to 'C' in initialization" "" { target c++14_down } }
+ J c6 {c + 5}; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } }
+}
+
+template <typename L>
+struct U3
+{
+ U3 () : e { 5 } {} // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } }
+ U3 (int) : e { 5.0 } {}// { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } }
+ // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 }
+ U3 (float) : e({ 6 }) {}
+ L e;
+};
+
+template <typename H, typename I, typename J, typename K>
+struct W3
+{
+ H a { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" "" { target *-*-* } .-2 }
+ I b { 6 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } .-3 }
+ J c { 3.0f }; // { dg-error "cannot convert \[^\n\r]* to 'C' in initialization" "" { target c++14_down } .-4 }
+ // { dg-error "narrowing conversion of '3.0e.0f' from 'float' to 'int' inside" "" { target c++1z } .-5 }
+ K d = { 7 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target *-*-* } .-6 }
+};
+
+void
+test ()
+{
+ foo2<0> ();
+ U2<0> u20;
+ U2<1> u21 (5);
+ W2<0> w2; // { dg-error "invalid conversion from 'int' to 'A'" }
+ // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } .-1 }
+ // { dg-error "cannot convert \[^\n\r]* to 'C' in initialization" "" { target c++14_down } .-2 }
+ // { dg-error "narrowing conversion of '3.0e.0f' from 'float' to 'int' inside" "" { target c++1z } .-3 }
+ // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target *-*-* } .-4 }
+ foo3<A, B, C, D, E, V> ();
+ U3<E> u30;
+ U3<E> u31 (5);
+ W3<A, B, C, D> w3; // { dg-error "invalid conversion from 'int' to 'A'" }
+ // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } .-1 }
+ // { dg-error "cannot convert \[^\n\r]* to 'C' in initialization" "" { target c++14_down } .-2 }
+ // { dg-error "narrowing conversion of '3.0e.0f' from 'float' to 'int' inside" "" { target c++1z } .-3 }
+ // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target *-*-* } .-4 }
+}