[clang] [clang] function template non-call partial ordering fixes (PR #106829)

via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 31 02:36:04 PDT 2024


================
@@ -5635,123 +5627,95 @@ static bool isAtLeastAsSpecializedAs(Sema &S, SourceLocation Loc,
 
   assert(Proto1 && Proto2 && "Function templates must have prototypes");
   TemplateParameterList *TemplateParams = FT2->getTemplateParameters();
-  SmallVector<DeducedTemplateArgument, 4> Deduced;
-  Deduced.resize(TemplateParams->size());
+  SmallVector<DeducedTemplateArgument, 4> Deduced(TemplateParams->size());
 
-  // C++0x [temp.deduct.partial]p3:
-  //   The types used to determine the ordering depend on the context in which
-  //   the partial ordering is done:
   TemplateDeductionInfo Info(Loc);
-  switch (TPOC) {
-  case TPOC_Call: {
-    llvm::SmallBitVector HasDeducedParam(Args2.size());
-    if (DeduceTemplateArguments(
-            S, TemplateParams, Args2.data(), Args2.size(), Args1.data(),
-            Args1.size(), Info, Deduced, TDF_None, /*PartialOrdering=*/true,
-            /*HasDeducedAnyParam=*/nullptr,
-            &HasDeducedParam) != TemplateDeductionResult::Success)
-      return false;
+  if (TPOC == TPOC_Other) {
+    // We wouldn't be partial ordering these candidates if these didn't match.
+    assert(Proto2->getMethodQuals() == Proto1->getMethodQuals());
+    assert(Proto2->getRefQualifier() == Proto1->getRefQualifier());
+    assert(Proto2->isVariadic() == Proto1->isVariadic());
 
-    SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),
-                                                 Deduced.end());
-    Sema::InstantiatingTemplate Inst(
-        S, Info.getLocation(), FT2, DeducedArgs,
-        Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info);
-    if (Inst.isInvalid())
-      return false;
-
-    bool AtLeastAsSpecialized = true;
-    S.runWithSufficientStackSpace(Info.getLocation(), [&] {
-      AtLeastAsSpecialized =
-          ::FinishTemplateArgumentDeduction(
-              S, FT2, Deduced, Info,
-              [&](Sema &S, FunctionTemplateDecl *FTD,
-                  ArrayRef<TemplateArgument> DeducedArgs) {
-                return ::DeduceForEachType(
-                    S, TemplateParams, Args2.data(), Args2.size(), Args1.data(),
-                    Args1.size(), Info, Deduced,
-                    /*PartialOrdering=*/true, /*FinishingDeduction=*/true,
-                    [&](Sema &S, TemplateParameterList *, int ParamIdx,
-                        int ArgIdx, QualType P, QualType A,
-                        TemplateDeductionInfo &Info,
-                        SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                        bool) {
-                      // As a provisional fix for a core issue that does not
-                      // exist yet, only check the consistency of parameters
-                      // which participated in deduction. We still try to
-                      // substitute them though.
-                      return ::CheckDeductionConsistency(
-                          S, FTD, ArgIdx, P, A, DeducedArgs,
-                          HasDeducedParam[ParamIdx]);
-                    });
-              }) == TemplateDeductionResult::Success;
-    });
-    if (!AtLeastAsSpecialized)
-      return false;
-  } break;
-  case TPOC_Conversion:
-  case TPOC_Other: {
-    //   - In the context of a call to a conversion operator, the return types
-    //     of the conversion function templates are used.
-    //   - In other contexts (14.6.6.2) the function template's function type
-    //     is used.
-    auto [A, P, TDF] = TPOC == TPOC_Other
-                           ? std::make_tuple(FD1->getType(), FD2->getType(),
-                                             TDF_AllowCompatibleFunctionType)
-                           : std::make_tuple(Proto1->getReturnType(),
-                                             Proto2->getReturnType(), TDF_None);
+    assert(Args1.empty() && Args2.empty());
+    Args1 = Proto1->getParamTypes();
+    Args2 = Proto2->getParamTypes();
+  }
+  // C++26 [temp.deduct.partial]p3:
+  //   The types used to determine the ordering depend on the context in which
+  //   the partial ordering is done:
+  //   - In the context of a function call, the types used are those function
+  //     parameter types for which the function call has arguments.
+  //   - In the context of a call to a conversion operator, the return types
+  //     of the conversion function templates are used.
+  //   - In other contexts (14.6.6.2) the function template's function type
+  //     is used.
+  bool HasDeducedAnyParamFromReturnType = false;
+  if (TPOC != TPOC_Call) {
     if (DeduceTemplateArgumentsByTypeMatch(
-            S, TemplateParams, P, A, Info, Deduced, TDF,
+            S, TemplateParams, Proto2->getReturnType(), Proto1->getReturnType(),
+            Info, Deduced, TDF_None,
             /*PartialOrdering=*/true, /*DeducedFromArrayBound=*/false,
-            /*HasDeducedAnyParam=*/nullptr) != TemplateDeductionResult::Success)
+            &HasDeducedAnyParamFromReturnType) !=
+        TemplateDeductionResult::Success)
       return false;
+  }
 
-    SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),
-                                                 Deduced.end());
-    Sema::InstantiatingTemplate Inst(
-        S, Info.getLocation(), FT2, DeducedArgs,
-        Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info);
-    if (Inst.isInvalid())
+  llvm::SmallBitVector HasDeducedParam;
+  if (TPOC != TPOC_Conversion) {
+    HasDeducedParam.resize(Args2.size());
+    if (DeduceTemplateArguments(S, TemplateParams, Args2, Args1, Info, Deduced,
+                                TDF_None, /*PartialOrdering=*/true,
+                                /*HasDeducedAnyParam=*/nullptr,
+                                &HasDeducedParam) !=
+        TemplateDeductionResult::Success)
       return false;
+  }
 
-    bool AtLeastAsSpecialized;
-    S.runWithSufficientStackSpace(Info.getLocation(), [&] {
-      AtLeastAsSpecialized =
-          ::FinishTemplateArgumentDeduction(
-              S, FT2, Deduced, Info,
-              [&](Sema &S, FunctionTemplateDecl *FTD,
-                  ArrayRef<TemplateArgument> DeducedArgs) {
+  SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
+  Sema::InstantiatingTemplate Inst(
+      S, Info.getLocation(), FT2, DeducedArgs,
+      Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info);
+  if (Inst.isInvalid())
+    return false;
+
+  bool AtLeastAsSpecialized;
+  S.runWithSufficientStackSpace(Info.getLocation(), [&] {
+    AtLeastAsSpecialized =
+        ::FinishTemplateArgumentDeduction(
+            S, FT2, Deduced, Info,
+            [&](Sema &S, FunctionTemplateDecl *FTD,
+                ArrayRef<TemplateArgument> DeducedArgs) {
+              // As a provisional fix for a core issue that does not
+              // exist yet, , which may be related to CWG2160, only check the
----------------
cor3ntin wrote:

```suggestion
              // As a provisional fix for a core issue that does not
              // exist yet, which may be related to CWG2160, only check the
```

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


More information about the cfe-commits mailing list