]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: defaulted ctor vs template ctor [PR125135]
authorJason Merrill <jason@redhat.com>
Fri, 22 May 2026 16:57:09 +0000 (12:57 -0400)
committerJason Merrill <jason@redhat.com>
Sat, 23 May 2026 04:25:42 +0000 (00:25 -0400)
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.

gcc/cp/pt.cc
gcc/testsuite/g++.dg/cpp0x/implicit18.C [new file with mode: 0644]

index 91aa9f5560228f8b42d258ff817fed4334e62832..3910017a9dc9e36862d9c1fbc4a9c462c650e94a 100644 (file)
@@ -23924,6 +23924,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 (file)
index 0000000..5b3730f
--- /dev/null
@@ -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;