aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2023-03-17 18:25:13 -0400
committerMarek Polacek <polacek@redhat.com>2023-03-20 16:54:11 -0400
commita226590fefb35ed66adf73d85cefe49048a78ab8 (patch)
treee28402d0be762f0e62247b7c5978b0f4de753961 /gcc
parent0a846340b99675d57fc2f2923a0412134eed09d3 (diff)
downloadgcc-a226590fefb35ed66adf73d85cefe49048a78ab8.zip
gcc-a226590fefb35ed66adf73d85cefe49048a78ab8.tar.gz
gcc-a226590fefb35ed66adf73d85cefe49048a78ab8.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/call.cc4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/explicit16.C18
2 files changed, 21 insertions, 1 deletions
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<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);
+}