From a226590fefb35ed66adf73d85cefe49048a78ab8 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 17 Mar 2023 18:25:13 -0400 Subject: c++: explicit ctor and list-initialization [PR109159] 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. 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 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/explicit16.C (limited to 'gcc') diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index c01e7b8..c52a09b 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 0000000..bb5a823 --- /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 + 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); +} -- cgit v1.1