c++: explicit ctor and list-initialization [PR109159]
Commit Message
When I implemented explicit(bool) in r9-3735, I added this code to
add_template_candidate_real:
+ /* Now the explicit specifier might have been deduced; check if this
+ declaration is explicit. If it is and we're ignoring non-converting
+ constructors, don't add this function to the set of candidates. */
+ if ((flags & LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (fn))
+ return NULL;
but as this test demonstrates, that's incorrect when we're initializing
from a {}: for list-initialization we consider explicit constructors and
complain if one is chosen.
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/12?
PR c++/109159
gcc/cp/ChangeLog:
* call.cc (add_template_candidate_real): Add explicit decls to the
set of candidates when the initializer is a braced-init-list.
libstdc++-v3/ChangeLog:
* testsuite/20_util/pair/cons/explicit_construct.cc: Adjust dg-error.
* testsuite/20_util/tuple/cons/explicit_construct.cc: Likewise.
* testsuite/23_containers/span/explicit.cc: Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/explicit16.C: New test.
---
gcc/cp/call.cc | 4 +-
gcc/testsuite/g++.dg/cpp0x/explicit16.C | 18 ++++++
.../20_util/pair/cons/explicit_construct.cc | 10 ++--
.../20_util/tuple/cons/explicit_construct.cc | 58 +++++++++----------
.../testsuite/23_containers/span/explicit.cc | 4 +-
5 files changed, 57 insertions(+), 37 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/explicit16.C
base-commit: fbd50e867e6a782c7b56c9727bf7e1e74dae4b94
Comments
On 3/20/23 11:55, Marek Polacek wrote:
> When I implemented explicit(bool) in r9-3735, I added this code to
> add_template_candidate_real:
> + /* Now the explicit specifier might have been deduced; check if this
> + declaration is explicit. If it is and we're ignoring non-converting
> + constructors, don't add this function to the set of candidates. */
> + if ((flags & LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (fn))
> + return NULL;
> but as this test demonstrates, that's incorrect when we're initializing
> from a {}: for list-initialization we consider explicit constructors and
> complain if one is chosen.
>
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/12?
OK.
> PR c++/109159
>
> gcc/cp/ChangeLog:
>
> * call.cc (add_template_candidate_real): Add explicit decls to the
> set of candidates when the initializer is a braced-init-list.
>
> libstdc++-v3/ChangeLog:
>
> * testsuite/20_util/pair/cons/explicit_construct.cc: Adjust dg-error.
> * testsuite/20_util/tuple/cons/explicit_construct.cc: Likewise.
> * testsuite/23_containers/span/explicit.cc: Likewise.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/cpp0x/explicit16.C: New test.
> ---
> gcc/cp/call.cc | 4 +-
> gcc/testsuite/g++.dg/cpp0x/explicit16.C | 18 ++++++
> .../20_util/pair/cons/explicit_construct.cc | 10 ++--
> .../20_util/tuple/cons/explicit_construct.cc | 58 +++++++++----------
> .../testsuite/23_containers/span/explicit.cc | 4 +-
> 5 files changed, 57 insertions(+), 37 deletions(-)
> create mode 100644 gcc/testsuite/g++.dg/cpp0x/explicit16.C
>
> diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
> index c01e7b82457..c52a09b9be2 100644
> --- a/gcc/cp/call.cc
> +++ b/gcc/cp/call.cc
> @@ -3612,7 +3612,9 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
> /* Now the explicit specifier might have been deduced; check if this
> declaration is explicit. If it is and we're ignoring non-converting
> constructors, don't add this function to the set of candidates. */
> - if ((flags & LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (fn))
> + if (((flags & (LOOKUP_ONLYCONVERTING|LOOKUP_LIST_INIT_CTOR))
> + == LOOKUP_ONLYCONVERTING)
> + && DECL_NONCONVERTING_P (fn))
> return NULL;
>
> if (DECL_CONSTRUCTOR_P (fn) && nargs == 2)
> diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit16.C b/gcc/testsuite/g++.dg/cpp0x/explicit16.C
> new file mode 100644
> index 00000000000..bb5a823aee6
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/explicit16.C
> @@ -0,0 +1,18 @@
> +// PR c++/109159
> +// { dg-do compile { target c++11 } }
> +
> +struct A {
> + A(float) {}
> + template<class U>
> + explicit A(U) {}
> +};
> +
> +void f(A t)
> +{
> + t = {1}; // { dg-error "explicit constructor" }
> + t = 1;
> + A a1{1};
> + A a2 = {1}; // { dg-error "explicit constructor" }
> + A a3 = 1;
> + A a4(1);
> +}
> diff --git a/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc b/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc
> index e875f0cbcd2..d550e9c604b 100644
> --- a/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc
> +++ b/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc
> @@ -37,7 +37,7 @@ struct ExplicitDefaultDefault
>
> std::pair<int, int> f1() {return {1,2};}
>
> -std::pair<Explicit, Explicit> f2() {return {1,2};} // { dg-error "could not convert" }
> +std::pair<Explicit, Explicit> f2() {return {1,2};} // { dg-error "explicit constructor" }
>
> std::pair<long, long> f3() {return std::pair<int, int>{1,2};}
>
> @@ -52,7 +52,7 @@ std::pair<int, int> v0{1,2};
>
> std::pair<Explicit, Explicit> v1{1,2};
>
> -std::pair<Explicit, Explicit> v2 = {1,2}; // { dg-error "could not convert" }
> +std::pair<Explicit, Explicit> v2 = {1,2}; // { dg-error "explicit constructor" }
>
> std::pair<Explicit, Explicit> v3{std::pair<int,int>{1,2}};
>
> @@ -99,7 +99,7 @@ void test_arg_passing()
> {
> f6(v0); // { dg-error "could not convert" }
> f6(v1);
> - f6({1,2}); // { dg-error "could not convert" }
> + f6({1,2}); // { dg-error "explicit constructor" }
> f6(std::pair<Explicit, Explicit>{});
> f6(std::pair<int, int>{}); // { dg-error "could not convert" }
> f7(v0);
> @@ -130,6 +130,6 @@ std::pair<int*, ExplicitMoveOnly> v14{nullptr, MoveOnly{}};
> std::pair<ExplicitMoveOnly, int*> v15{MoveOnly{}, nullptr};
>
> std::pair<int*, ExplicitMoveOnly> v16 =
> - {nullptr, MoveOnly{}}; // { dg-error "could not convert" }
> + {nullptr, MoveOnly{}}; // { dg-error "explicit constructor" }
> std::pair<ExplicitMoveOnly, int*> v17 =
> - {MoveOnly{}, nullptr}; // { dg-error "could not convert" }
> + {MoveOnly{}, nullptr}; // { dg-error "explicit constructor" }
> diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc
> index 820ddef30b4..3352dd15f7d 100644
> --- a/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc
> +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc
> @@ -45,11 +45,11 @@ std::tuple<int, int> f1b() {return {1,2};}
> std::tuple<int, int, int> f1c() {return {1,2,3};}
>
> std::tuple<Explicit> f2_a()
> -{return {1};} // { dg-error "could not convert" }
> +{return {1};} // { dg-error "explicit constructor" }
> std::tuple<Explicit, Explicit> f2_b()
> -{return {1,2};} // { dg-error "could not convert" }
> +{return {1,2};} // { dg-error "explicit constructor" }
> std::tuple<Explicit, Explicit, Explicit> f2_c()
> -{return {1,2,3};} // { dg-error "could not convert" }
> +{return {1,2,3};} // { dg-error "explicit constructor" }
>
> std::tuple<long> f3_a() {return std::tuple<int>{1};}
> std::tuple<long, long> f3_b() {return std::tuple<int, int>{1,2};}
> @@ -73,22 +73,22 @@ std::tuple<long, long> f5_b() {return {1,2};}
> std::tuple<long, long, long> f5_c() {return {1,2,3};}
>
> std::tuple<ExplicitDefault> f6_a()
> -{return {};} // { dg-error "could not convert" }
> +{return {};} // { dg-error "explicit constructor" }
> std::tuple<ExplicitDefault, ExplicitDefault> f6_b()
> -{return {};} // { dg-error "could not convert" }
> +{return {};} // { dg-error "explicit constructor" }
> std::tuple<ExplicitDefault, ExplicitDefault, ExplicitDefault> f6_c()
> -{return {};} // { dg-error "could not convert" }
> +{return {};} // { dg-error "explicit constructor" }
> std::tuple<ExplicitDefault, int> f6_d()
> -{return {};} // { dg-error "could not convert" }
> +{return {};} // { dg-error "explicit constructor" }
>
> std::tuple<ExplicitDefaultDefault> f7_a()
> -{return {};} // { dg-error "could not convert" }
> +{return {};} // { dg-error "explicit constructor" }
> std::tuple<ExplicitDefaultDefault, ExplicitDefaultDefault> f7_b()
> -{return {};} // { dg-error "could not convert" }
> +{return {};} // { dg-error "explicit constructor" }
> std::tuple<ExplicitDefaultDefault,
> ExplicitDefaultDefault,
> ExplicitDefaultDefault> f7_c()
> -{return {};} // { dg-error "could not convert" }
> +{return {};} // { dg-error "explicit constructor" }
>
> std::tuple<int, int> fp1() {return std::pair<int, int>{1,2}; }
> std::tuple<long, long> fp2() {return std::pair<int, int>{1,2}; }
> @@ -103,9 +103,9 @@ std::tuple<Explicit> v1_a{1};
> std::tuple<Explicit, Explicit> v1_b{1,2};
> std::tuple<Explicit, Explicit, Explicit> v1_c{1,2,3};
>
> -std::tuple<Explicit> v2_a = {1}; // { dg-error "could not convert" }
> -std::tuple<Explicit, Explicit> v2_b = {1,2}; // { dg-error "could not convert" }
> -std::tuple<Explicit, Explicit, Explicit> v2_c = {1,2,3}; // { dg-error "could not convert" }
> +std::tuple<Explicit> v2_a = {1}; // { dg-error "explicit constructor" }
> +std::tuple<Explicit, Explicit> v2_b = {1,2}; // { dg-error "explicit constructor" }
> +std::tuple<Explicit, Explicit, Explicit> v2_c = {1,2,3}; // { dg-error "explicit constructor" }
>
> std::tuple<Explicit> v3_a{std::tuple<int>{1}};
> std::tuple<Explicit, Explicit> v3_b{std::tuple<int,int>{1,2}};
> @@ -196,11 +196,11 @@ std::tuple<long, long, long>
> v31_c{std::allocator_arg, std::allocator<int>{}, 1,2,3};
>
> std::tuple<Explicit> v32_a
> - = {std::allocator_arg, std::allocator<int>{ }, 1}; // { dg-error "could not convert" }
> + = {std::allocator_arg, std::allocator<int>{ }, 1}; // { dg-error "explicit constructor" }
> std::tuple<Explicit, Explicit> v32_b
> - = {std::allocator_arg, std::allocator<int>{}, 1, 2}; // { dg-error "could not convert" }
> + = {std::allocator_arg, std::allocator<int>{}, 1, 2}; // { dg-error "explicit constructor" }
> std::tuple<Explicit, Explicit, Explicit> v32_c
> - = {std::allocator_arg, std::allocator<int>{}, 1,2,3}; // { dg-error "could not convert" }
> + = {std::allocator_arg, std::allocator<int>{}, 1,2,3}; // { dg-error "explicit constructor" }
>
> std::tuple<int, int> v33{std::allocator_arg, std::allocator<int>{},
> std::pair<int, int>{1, 2}};
> @@ -218,7 +218,7 @@ std::tuple<long, long> v37 = {std::allocator_arg, std::allocator<int>{},
> std::pair<int, int>{1, 2}};
>
> std::tuple<Explicit, Explicit> v38
> -= {std::allocator_arg, std::allocator<int>{}, std::pair<int, int>{1, 2}}; // { dg-error "could not convert" }
> += {std::allocator_arg, std::allocator<int>{}, std::pair<int, int>{1, 2}}; // { dg-error "explicit constructor" }
>
> std::tuple<int, int> v39{std::allocator_arg, std::allocator<int>{}, v20};
>
> @@ -232,18 +232,18 @@ std::tuple<int, int> v42 = {std::allocator_arg, std::allocator<int>{}, v20};
> std::tuple<long, long> v43 = {std::allocator_arg, std::allocator<int>{}, v20};
>
> std::tuple<Explicit, Explicit> v44
> -= {std::allocator_arg, std::allocator<int>{ }, v20}; // { dg-error "could not convert" }
> += {std::allocator_arg, std::allocator<int>{ }, v20}; // { dg-error "explicit constructor" }
> std::tuple<ExplicitDefault> v45_a{};
> std::tuple<ExplicitDefault, int> v45_b{};
>
> -std::tuple<ExplicitDefault> v46_a = {}; // { dg-error "could not convert" }
> -std::tuple<ExplicitDefault, int> v46_b = {}; // { dg-error "could not convert" }
> +std::tuple<ExplicitDefault> v46_a = {}; // { dg-error "explicit constructor" }
> +std::tuple<ExplicitDefault, int> v46_b = {}; // { dg-error "explicit constructor" }
>
> std::tuple<ExplicitDefaultDefault> v47_a{};
> std::tuple<ExplicitDefaultDefault, int> v47_b{};
>
> -std::tuple<ExplicitDefaultDefault> v48_a = {}; // { dg-error "could not convert" }
> -std::tuple<ExplicitDefaultDefault, int> v48_b = { }; // { dg-error "could not convert" }
> +std::tuple<ExplicitDefaultDefault> v48_a = {}; // { dg-error "explicit constructor" }
> +std::tuple<ExplicitDefaultDefault, int> v48_b = { }; // { dg-error "explicit constructor" }
>
>
> struct DeletedCopy
> @@ -295,9 +295,9 @@ void test_arg_passing()
> f8_b(v1_b);
> f8_c(v1_c);
>
> - f8_a({1}); // { dg-error "could not convert" }
> - f8_b({1,2}); // { dg-error "could not convert" }
> - f8_c({1,2,3}); // { dg-error "could not convert" }
> + f8_a({1}); // { dg-error "explicit constructor" }
> + f8_b({1,2}); // { dg-error "explicit constructor" }
> + f8_c({1,2,3}); // { dg-error "explicit constructor" }
>
> f8_a(std::tuple<Explicit>{});
> f8_b(std::tuple<Explicit, Explicit>{});
> @@ -330,10 +330,10 @@ void test_arg_passing()
> f9_b(std::tuple<long, long>{});
> f9_c(std::tuple<long, long, long>{});
>
> - f10_a({}); // { dg-error "could not convert" }
> - f10_b({}); // { dg-error "could not convert" }
> - f11_a({}); // { dg-error "could not convert" }
> - f11_b({}); // { dg-error "could not convert" }
> + f10_a({}); // { dg-error "explicit constructor" }
> + f10_b({}); // { dg-error "explicit constructor" }
> + f11_a({}); // { dg-error "explicit constructor" }
> + f11_b({}); // { dg-error "explicit constructor" }
>
> f10_a(std::tuple<ExplicitDefault>{});
> f10_b(std::tuple<ExplicitDefault, int>{});
> diff --git a/libstdc++-v3/testsuite/23_containers/span/explicit.cc b/libstdc++-v3/testsuite/23_containers/span/explicit.cc
> index 580d69e4f09..b0a1311f02c 100644
> --- a/libstdc++-v3/testsuite/23_containers/span/explicit.cc
> +++ b/libstdc++-v3/testsuite/23_containers/span/explicit.cc
> @@ -31,11 +31,11 @@ auto first = std::begin(r), last = std::end(r);
>
> // span(It, size_type)
> std::span<int> s1 = {first, 2};
> -std::span<int, 2> s2 = {first, 2}; // { dg-error "could not convert" }
> +std::span<int, 2> s2 = {first, 2}; // { dg-error "explicit constructor" }
>
> // span(It, End)
> std::span<int> s3 = {first, last};
> -std::span<int, 2> s4 = {first, last}; // { dg-error "could not convert" }
> +std::span<int, 2> s4 = {first, last}; // { dg-error "explicit constructor" }
>
> // span(R&&)
> std::span<int> s5 = r;
>
> base-commit: fbd50e867e6a782c7b56c9727bf7e1e74dae4b94
@@ -3612,7 +3612,9 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
/* Now the explicit specifier might have been deduced; check if this
declaration is explicit. If it is and we're ignoring non-converting
constructors, don't add this function to the set of candidates. */
- if ((flags & LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (fn))
+ if (((flags & (LOOKUP_ONLYCONVERTING|LOOKUP_LIST_INIT_CTOR))
+ == LOOKUP_ONLYCONVERTING)
+ && DECL_NONCONVERTING_P (fn))
return NULL;
if (DECL_CONSTRUCTOR_P (fn) && nargs == 2)
new file mode 100644
@@ -0,0 +1,18 @@
+// PR c++/109159
+// { dg-do compile { target c++11 } }
+
+struct A {
+ A(float) {}
+ template<class U>
+ explicit A(U) {}
+};
+
+void f(A t)
+{
+ t = {1}; // { dg-error "explicit constructor" }
+ t = 1;
+ A a1{1};
+ A a2 = {1}; // { dg-error "explicit constructor" }
+ A a3 = 1;
+ A a4(1);
+}
@@ -37,7 +37,7 @@ struct ExplicitDefaultDefault
std::pair<int, int> f1() {return {1,2};}
-std::pair<Explicit, Explicit> f2() {return {1,2};} // { dg-error "could not convert" }
+std::pair<Explicit, Explicit> f2() {return {1,2};} // { dg-error "explicit constructor" }
std::pair<long, long> f3() {return std::pair<int, int>{1,2};}
@@ -52,7 +52,7 @@ std::pair<int, int> v0{1,2};
std::pair<Explicit, Explicit> v1{1,2};
-std::pair<Explicit, Explicit> v2 = {1,2}; // { dg-error "could not convert" }
+std::pair<Explicit, Explicit> v2 = {1,2}; // { dg-error "explicit constructor" }
std::pair<Explicit, Explicit> v3{std::pair<int,int>{1,2}};
@@ -99,7 +99,7 @@ void test_arg_passing()
{
f6(v0); // { dg-error "could not convert" }
f6(v1);
- f6({1,2}); // { dg-error "could not convert" }
+ f6({1,2}); // { dg-error "explicit constructor" }
f6(std::pair<Explicit, Explicit>{});
f6(std::pair<int, int>{}); // { dg-error "could not convert" }
f7(v0);
@@ -130,6 +130,6 @@ std::pair<int*, ExplicitMoveOnly> v14{nullptr, MoveOnly{}};
std::pair<ExplicitMoveOnly, int*> v15{MoveOnly{}, nullptr};
std::pair<int*, ExplicitMoveOnly> v16 =
- {nullptr, MoveOnly{}}; // { dg-error "could not convert" }
+ {nullptr, MoveOnly{}}; // { dg-error "explicit constructor" }
std::pair<ExplicitMoveOnly, int*> v17 =
- {MoveOnly{}, nullptr}; // { dg-error "could not convert" }
+ {MoveOnly{}, nullptr}; // { dg-error "explicit constructor" }
@@ -45,11 +45,11 @@ std::tuple<int, int> f1b() {return {1,2};}
std::tuple<int, int, int> f1c() {return {1,2,3};}
std::tuple<Explicit> f2_a()
-{return {1};} // { dg-error "could not convert" }
+{return {1};} // { dg-error "explicit constructor" }
std::tuple<Explicit, Explicit> f2_b()
-{return {1,2};} // { dg-error "could not convert" }
+{return {1,2};} // { dg-error "explicit constructor" }
std::tuple<Explicit, Explicit, Explicit> f2_c()
-{return {1,2,3};} // { dg-error "could not convert" }
+{return {1,2,3};} // { dg-error "explicit constructor" }
std::tuple<long> f3_a() {return std::tuple<int>{1};}
std::tuple<long, long> f3_b() {return std::tuple<int, int>{1,2};}
@@ -73,22 +73,22 @@ std::tuple<long, long> f5_b() {return {1,2};}
std::tuple<long, long, long> f5_c() {return {1,2,3};}
std::tuple<ExplicitDefault> f6_a()
-{return {};} // { dg-error "could not convert" }
+{return {};} // { dg-error "explicit constructor" }
std::tuple<ExplicitDefault, ExplicitDefault> f6_b()
-{return {};} // { dg-error "could not convert" }
+{return {};} // { dg-error "explicit constructor" }
std::tuple<ExplicitDefault, ExplicitDefault, ExplicitDefault> f6_c()
-{return {};} // { dg-error "could not convert" }
+{return {};} // { dg-error "explicit constructor" }
std::tuple<ExplicitDefault, int> f6_d()
-{return {};} // { dg-error "could not convert" }
+{return {};} // { dg-error "explicit constructor" }
std::tuple<ExplicitDefaultDefault> f7_a()
-{return {};} // { dg-error "could not convert" }
+{return {};} // { dg-error "explicit constructor" }
std::tuple<ExplicitDefaultDefault, ExplicitDefaultDefault> f7_b()
-{return {};} // { dg-error "could not convert" }
+{return {};} // { dg-error "explicit constructor" }
std::tuple<ExplicitDefaultDefault,
ExplicitDefaultDefault,
ExplicitDefaultDefault> f7_c()
-{return {};} // { dg-error "could not convert" }
+{return {};} // { dg-error "explicit constructor" }
std::tuple<int, int> fp1() {return std::pair<int, int>{1,2}; }
std::tuple<long, long> fp2() {return std::pair<int, int>{1,2}; }
@@ -103,9 +103,9 @@ std::tuple<Explicit> v1_a{1};
std::tuple<Explicit, Explicit> v1_b{1,2};
std::tuple<Explicit, Explicit, Explicit> v1_c{1,2,3};
-std::tuple<Explicit> v2_a = {1}; // { dg-error "could not convert" }
-std::tuple<Explicit, Explicit> v2_b = {1,2}; // { dg-error "could not convert" }
-std::tuple<Explicit, Explicit, Explicit> v2_c = {1,2,3}; // { dg-error "could not convert" }
+std::tuple<Explicit> v2_a = {1}; // { dg-error "explicit constructor" }
+std::tuple<Explicit, Explicit> v2_b = {1,2}; // { dg-error "explicit constructor" }
+std::tuple<Explicit, Explicit, Explicit> v2_c = {1,2,3}; // { dg-error "explicit constructor" }
std::tuple<Explicit> v3_a{std::tuple<int>{1}};
std::tuple<Explicit, Explicit> v3_b{std::tuple<int,int>{1,2}};
@@ -196,11 +196,11 @@ std::tuple<long, long, long>
v31_c{std::allocator_arg, std::allocator<int>{}, 1,2,3};
std::tuple<Explicit> v32_a
- = {std::allocator_arg, std::allocator<int>{ }, 1}; // { dg-error "could not convert" }
+ = {std::allocator_arg, std::allocator<int>{ }, 1}; // { dg-error "explicit constructor" }
std::tuple<Explicit, Explicit> v32_b
- = {std::allocator_arg, std::allocator<int>{}, 1, 2}; // { dg-error "could not convert" }
+ = {std::allocator_arg, std::allocator<int>{}, 1, 2}; // { dg-error "explicit constructor" }
std::tuple<Explicit, Explicit, Explicit> v32_c
- = {std::allocator_arg, std::allocator<int>{}, 1,2,3}; // { dg-error "could not convert" }
+ = {std::allocator_arg, std::allocator<int>{}, 1,2,3}; // { dg-error "explicit constructor" }
std::tuple<int, int> v33{std::allocator_arg, std::allocator<int>{},
std::pair<int, int>{1, 2}};
@@ -218,7 +218,7 @@ std::tuple<long, long> v37 = {std::allocator_arg, std::allocator<int>{},
std::pair<int, int>{1, 2}};
std::tuple<Explicit, Explicit> v38
-= {std::allocator_arg, std::allocator<int>{}, std::pair<int, int>{1, 2}}; // { dg-error "could not convert" }
+= {std::allocator_arg, std::allocator<int>{}, std::pair<int, int>{1, 2}}; // { dg-error "explicit constructor" }
std::tuple<int, int> v39{std::allocator_arg, std::allocator<int>{}, v20};
@@ -232,18 +232,18 @@ std::tuple<int, int> v42 = {std::allocator_arg, std::allocator<int>{}, v20};
std::tuple<long, long> v43 = {std::allocator_arg, std::allocator<int>{}, v20};
std::tuple<Explicit, Explicit> v44
-= {std::allocator_arg, std::allocator<int>{ }, v20}; // { dg-error "could not convert" }
+= {std::allocator_arg, std::allocator<int>{ }, v20}; // { dg-error "explicit constructor" }
std::tuple<ExplicitDefault> v45_a{};
std::tuple<ExplicitDefault, int> v45_b{};
-std::tuple<ExplicitDefault> v46_a = {}; // { dg-error "could not convert" }
-std::tuple<ExplicitDefault, int> v46_b = {}; // { dg-error "could not convert" }
+std::tuple<ExplicitDefault> v46_a = {}; // { dg-error "explicit constructor" }
+std::tuple<ExplicitDefault, int> v46_b = {}; // { dg-error "explicit constructor" }
std::tuple<ExplicitDefaultDefault> v47_a{};
std::tuple<ExplicitDefaultDefault, int> v47_b{};
-std::tuple<ExplicitDefaultDefault> v48_a = {}; // { dg-error "could not convert" }
-std::tuple<ExplicitDefaultDefault, int> v48_b = { }; // { dg-error "could not convert" }
+std::tuple<ExplicitDefaultDefault> v48_a = {}; // { dg-error "explicit constructor" }
+std::tuple<ExplicitDefaultDefault, int> v48_b = { }; // { dg-error "explicit constructor" }
struct DeletedCopy
@@ -295,9 +295,9 @@ void test_arg_passing()
f8_b(v1_b);
f8_c(v1_c);
- f8_a({1}); // { dg-error "could not convert" }
- f8_b({1,2}); // { dg-error "could not convert" }
- f8_c({1,2,3}); // { dg-error "could not convert" }
+ f8_a({1}); // { dg-error "explicit constructor" }
+ f8_b({1,2}); // { dg-error "explicit constructor" }
+ f8_c({1,2,3}); // { dg-error "explicit constructor" }
f8_a(std::tuple<Explicit>{});
f8_b(std::tuple<Explicit, Explicit>{});
@@ -330,10 +330,10 @@ void test_arg_passing()
f9_b(std::tuple<long, long>{});
f9_c(std::tuple<long, long, long>{});
- f10_a({}); // { dg-error "could not convert" }
- f10_b({}); // { dg-error "could not convert" }
- f11_a({}); // { dg-error "could not convert" }
- f11_b({}); // { dg-error "could not convert" }
+ f10_a({}); // { dg-error "explicit constructor" }
+ f10_b({}); // { dg-error "explicit constructor" }
+ f11_a({}); // { dg-error "explicit constructor" }
+ f11_b({}); // { dg-error "explicit constructor" }
f10_a(std::tuple<ExplicitDefault>{});
f10_b(std::tuple<ExplicitDefault, int>{});
@@ -31,11 +31,11 @@ auto first = std::begin(r), last = std::end(r);
// span(It, size_type)
std::span<int> s1 = {first, 2};
-std::span<int, 2> s2 = {first, 2}; // { dg-error "could not convert" }
+std::span<int, 2> s2 = {first, 2}; // { dg-error "explicit constructor" }
// span(It, End)
std::span<int> s3 = {first, last};
-std::span<int, 2> s4 = {first, last}; // { dg-error "could not convert" }
+std::span<int, 2> s4 = {first, last}; // { dg-error "explicit constructor" }
// span(R&&)
std::span<int> s5 = r;