GCC 11 gives an error for the following code which GCC 10 and Clang accept: struct NonMovable { NonMovable(NonMovable&&) = delete; }; template <class T> struct Maybe { NonMovable mMember; template <typename U> Maybe(Maybe<U>&&); }; void foo(Maybe<int>); void unlucky(Maybe<int>&& x) { Maybe<int> var{(Maybe<int>&&)x}; } The error is: main.cpp: In function ‘void unlucky(Maybe<int>&&)’: main.cpp:16:33: error: use of deleted function ‘Maybe<int>::Maybe(Maybe<int>&&)’ 16 | Maybe<int> var{(Maybe<int>&&)x}; | ^ main.cpp:6:8: note: ‘Maybe<int>::Maybe(Maybe<int>&&)’ is implicitly deleted because the default definition would be ill-formed: 6 | struct Maybe { | ^~~~~ main.cpp:6:8: error: use of deleted function ‘NonMovable::NonMovable(NonMovable&&)’ main.cpp:2:3: note: declared here 2 | NonMovable(NonMovable &&) = delete; | ^~~~~~~~~~ I believe the code should be accepted, with the deleted move constructor ignored during overload resolution and the templated constructor used instead. I explain my reasoning, with links to the standard, in more detail here: https://bugzilla.mozilla.org/show_bug.cgi?id=1710235#c22 Please let me know if I've overlooked something and the code really is invalid.
Rejected since r11-7287 c++: Tuple of self-dependent classes [PR96926] When compiling this testcase, trying to resolve the initialization for the tuple member ends up recursively considering the same set of tuple constructor overloads, and since two of them separately depend on is_constructible, the one we try second fails to instantiate is_constructible because we're still in the middle of instantiating it the first time. Fixed by implementing an optimization that someone suggested we were already doing: if we see a non-template candidate that is a perfect match for all arguments, we can skip considering template candidates at all. It would be enough to do this only when LOOKUP_DEFAULTED, but it shouldn't hurt in other cases. gcc/cp/ChangeLog: PR c++/96926 * call.c (perfect_conversion_p): New. (perfect_candidate_p): New. (add_candidates): Ignore templates after a perfect non-template.
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:f71ca97def69b8aeb046d716eaea2367736f505e commit r12-885-gf71ca97def69b8aeb046d716eaea2367736f505e Author: Jason Merrill <jason@redhat.com> Date: Tue May 18 12:06:36 2021 -0400 c++: "perfect" implicitly deleted move [PR100644] Here we were ignoring the template constructor because the implicit move constructor had all perfect conversions. But CWG1402 says that an implicitly deleted move constructor is ignored by overload resolution; we implement that instead by preferring any other candidate in joust, to get better diagnostics, but that means we need to handle that case here as well. gcc/cp/ChangeLog: PR c++/100644 * call.c (perfect_candidate_p): An implicitly deleted move is not perfect. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/implicit-delete1.C: New test.
The releases/gcc-11 branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:6384e940a6db379b0524465cf6cbbd0996b48485 commit r11-8431-g6384e940a6db379b0524465cf6cbbd0996b48485 Author: Jason Merrill <jason@redhat.com> Date: Tue May 18 12:06:36 2021 -0400 c++: "perfect" implicitly deleted move [PR100644] Here we were ignoring the template constructor because the implicit move constructor had all perfect conversions. But CWG1402 says that an implicitly deleted move constructor is ignored by overload resolution; we implement that instead by preferring any other candidate in joust, to get better diagnostics, but that means we need to handle that case here as well. gcc/cp/ChangeLog: PR c++/100644 * call.c (perfect_candidate_p): An implicitly deleted move is not perfect. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/implicit-delete1.C: New test.
Fixed for 11.2/12.