diff options
author | Marek Polacek <polacek@redhat.com> | 2023-03-17 18:25:13 -0400 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2023-03-20 16:54:11 -0400 |
commit | a226590fefb35ed66adf73d85cefe49048a78ab8 (patch) | |
tree | e28402d0be762f0e62247b7c5978b0f4de753961 /gcc | |
parent | 0a846340b99675d57fc2f2923a0412134eed09d3 (diff) | |
download | gcc-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.cc | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/explicit16.C | 18 |
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); +} |