[clang] [clang] Implement P2582R1: CTAD from inherited constructors (PR #98788)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 25 09:47:49 PST 2024


================
@@ -10615,6 +10615,40 @@ bool clang::isBetterOverloadCandidate(
     auto *Guide1 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand1.Function);
     auto *Guide2 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand2.Function);
     if (Guide1 && Guide2) {
+      //  -- F1 and F2 are generated from class template argument deduction
+      //  for a class D, and F2 is generated from inheriting constructors
+      //  from a base class of D while F1 is not, ...
+      bool G1Inherited = Guide1->getSourceDeductionGuide() &&
+                         Guide1->getSourceDeductionGuideKind() ==
+                             CXXDeductionGuideDecl::SourceDeductionGuideKind::
+                                 InheritedConstructor;
+      bool G2Inherited = Guide2->getSourceDeductionGuide() &&
+                         Guide2->getSourceDeductionGuideKind() ==
+                             CXXDeductionGuideDecl::SourceDeductionGuideKind::
+                                 InheritedConstructor;
+      if (Guide1->isImplicit() && Guide2->isImplicit() &&
+          G1Inherited != G2Inherited) {
+        const FunctionProtoType *FPT1 =
+            Guide1->getType()->getAs<FunctionProtoType>();
+        const FunctionProtoType *FPT2 =
+            Guide2->getType()->getAs<FunctionProtoType>();
+        assert(FPT1 && FPT2);
+
+        // ... and for each explicit function argument, the parameters of F1 and
+        // F2 are either both ellipses or have the same type
+        if (FPT1->isVariadic() == FPT2->isVariadic() &&
+            FPT1->getNumParams() == FPT2->getNumParams()) {
----------------
erichkeane wrote:

Is there a reason we can't just check the types of the functions here instead?  I would assume their prototypes to compare equal.  That said, the wording of `parameters are both ellipses or have the same type` seems intentionally designed for the purpose of excluding the return type (or, perhaps reference/cv specifiers?)?  

If so, I think I'd rather a variant of `hasSameType` that for something like, `hasSameParameterList`.  At that point, we could have IT check for similar variadics as well. We probably want to make sure that `(int, ...)` works too.

Also, I don't think the initial check is right?  Shouldn't that be an 'or' there instead of '&&'?  If both are `NumParams == 0 && isVariadic`, then we want to hit this condition as well.

https://github.com/llvm/llvm-project/pull/98788


More information about the cfe-commits mailing list