https://gcc.gnu.org/g:a7421d94bbe7a3c673187ffb4e62e8e1926c8c7b
commit r16-8957-ga7421d94bbe7a3c673187ffb4e62e8e1926c8c7b Author: Jason Merrill <[email protected]> Date: Sat May 23 00:26:30 2026 -0400 c++: defaulted ctor vs template ctor [PR125135] Here we were getting into a CWG1092 cycle again through check_non_deducible_conversions, trying to lazily declare the RE move constructor, looking for a constructor to move A, considering the constructor template which takes RE&, and so trying to lazily declare the RE constructors again. Let's break the cycle in the same way. PR c++/125135 gcc/cp/ChangeLog: * pt.cc (check_non_deducible_conversions): Handle LOOKUP_DEFAULTED. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/implicit18.C: New test. (cherry picked from commit fe059756ddc4ec4e357a73d6385fd93db202c66e) Diff: --- gcc/cp/pt.cc | 10 ++++++++++ gcc/testsuite/g++.dg/cpp0x/implicit18.C | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 41aa49848c35..4d14ee239d36 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -23916,6 +23916,16 @@ check_non_deducible_conversions (tree parms, const tree *args, unsigned nargs, conversion **conv_p = convs ? &convs[ia+offset] : NULL; int lflags = conv_flags (ia, nargs, fn, arg, flags); + /* As in add_function_candidate, don't consider conversion to an + unrelated type when LOOKUP_DEFAULTED. */ + if ((flags & LOOKUP_DEFAULTED) + && ia == 0 + && (DECL_CONSTRUCTOR_P (fn) + || DECL_ASSIGNMENT_OPERATOR_P (fn)) + && !reference_related_p (non_reference (parm), + DECL_CONTEXT (fn))) + return 1; + if (check_non_deducible_conversion (parm, arg, strict, lflags, conv_p, explain_p, noninst_only_p)) return 1; diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit18.C b/gcc/testsuite/g++.dg/cpp0x/implicit18.C new file mode 100644 index 000000000000..5b3730f14ecb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/implicit18.C @@ -0,0 +1,20 @@ +// PR c++/125135 +// { dg-do compile { target c++11 } } + +template <typename T> +struct A +{ + template <typename... Ts> // variadic causea ICE. + A(T&, const Ts&...){} // T& arg causes ICE. + + A(const A&) = delete; // causes ICE. +}; + +struct RE +{ + RE(): a(*this) {} + + A<RE> a; +}; + +RE re;
