[clang] [Clang][RFC] Bypass TAD during overload resolution if a perfect match exists (PR #133426)

Younan Zhang via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 31 22:57:05 PDT 2025


================
@@ -10933,27 +11096,100 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
   // -fgpu-exclude-wrong-side-overloads is off. When
   // -fgpu-exclude-wrong-side-overloads is on, all candidates are compared
   // uniformly in isBetterOverloadCandidate.
-  if (S.getLangOpts().CUDA && !S.getLangOpts().GPUExcludeWrongSideOverloads) {
-    const FunctionDecl *Caller = S.getCurFunctionDecl(/*AllowLambda=*/true);
-    bool ContainsSameSideCandidate =
-        llvm::any_of(Candidates, [&](OverloadCandidate *Cand) {
-          // Check viable function only.
-          return Cand->Viable && Cand->Function &&
-                 S.CUDA().IdentifyPreference(Caller, Cand->Function) ==
-                     SemaCUDA::CFP_SameSide;
-        });
-    if (ContainsSameSideCandidate) {
-      auto IsWrongSideCandidate = [&](OverloadCandidate *Cand) {
-        // Check viable function only to avoid unnecessary data copying/moving.
+  if (!S.getLangOpts().CUDA || S.getLangOpts().GPUExcludeWrongSideOverloads)
+    return;
+  const FunctionDecl *Caller = S.getCurFunctionDecl(/*AllowLambda=*/true);
+
+  bool ContainsSameSideCandidate =
+      llvm::any_of(Candidates, [&](const OverloadCandidate *Cand) {
+        // Check viable function only.
         return Cand->Viable && Cand->Function &&
                S.CUDA().IdentifyPreference(Caller, Cand->Function) ==
-                   SemaCUDA::CFP_WrongSide;
-      };
-      llvm::erase_if(Candidates, IsWrongSideCandidate);
+                   SemaCUDA::CFP_SameSide;
+      });
+
+  if (!ContainsSameSideCandidate)
+    return;
+
+  auto IsWrongSideCandidate = [&](const OverloadCandidate *Cand) {
+    // Check viable function only to avoid unnecessary data copying/moving.
+    return Cand->Viable && Cand->Function &&
+           S.CUDA().IdentifyPreference(Caller, Cand->Function) ==
+               SemaCUDA::CFP_WrongSide;
+  };
+  llvm::erase_if(Candidates, IsWrongSideCandidate);
+}
+
+/// Computes the best viable function (C++ 13.3.3)
+/// within an overload candidate set.
+///
+/// \param Loc The location of the function name (or operator symbol) for
+/// which overload resolution occurs.
+///
+/// \param Best If overload resolution was successful or found a deleted
+/// function, \p Best points to the candidate function found.
+///
+/// \returns The result of overload resolution.
+OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S,
+                                                           SourceLocation Loc,
+                                                           iterator &Best) {
+
+  assert(shouldDeferTemplateArgumentDeduction(S.getLangOpts()) ||
+         DeferredCandidates.empty() &&
+             "Unexpected deferred template candidate");
+
+  bool TwoPhaseResolution = !DeferredCandidates.empty();
+
+  if (TwoPhaseResolution) {
+
+    PerfectViableFunction(S, Loc, Best);
+    if (Best != end())
+      return ResultForBestCandidate(Best);
+
+    InjectNonDeducedTemplateCandidates(S);
+  }
+
+  return BestViableFunctionImpl(S, Loc, Best);
+}
+
+void OverloadCandidateSet::PerfectViableFunction(
+    Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best) {
+
+  Best = end();
+  for (auto It = begin(); It != end(); ++It) {
+    if (It->isPerfectMatch(S.getASTContext())) {
----------------
zyn0217 wrote:

maybe
```cpp
if (!It->isPerfectMatch(S.getASTContext()))
  continue;
```
to reduce the curley nesting.

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


More information about the cfe-commits mailing list