llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Adam Dangoor (adamtheturtle)

<details>
<summary>Changes</summary>

ADL revisits a specialization's template arguments along every incoming path. 
With a nested `Node&lt;T, T&gt;`, the number of distinct types is linear but 
the associated-namespace traversal grows exponentially.

Track visited template arguments separately from transitive base-class 
traversal. The regression covers both deep repeated arguments and a 
specialization encountered through a base and as a direct argument.

Fixes #<!-- -->235704.

Validation on macOS arm64 with assertions enabled, built independently against 
LLVM main `0a6c7b28e6a5ad99b4d564908a6dd0912f944328`:

- `clang`, `clang-tidy`, `clang-format`, and `FileCheck` build passed.
- Formatting checked with the compiler build's clang-format.
- adl: 11 upstream lit tests passed.

The original Linux AArch64 LLVM 23.1.4 measurements are in the linked issue. 
Those are single wall-clock samples, not statistical benchmarks.

Prepared with AI assistance (OpenAI Codex).


---
Full diff: https://github.com/llvm/llvm-project/pull/235714.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaLookup.cpp (+10-3) 
- (added) clang/test/SemaCXX/adl-repeated-template-arguments.cpp (+17) 


``````````diff
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 75cad0bb433f8..d6f3b4152c8c0 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -2906,6 +2906,10 @@ namespace {
       return ClassesTransitive.insert(RD);
     }
 
+    bool visitTemplateArguments(CXXRecordDecl *RD) {
+      return ClassesWithVisitedTemplateArguments.insert(RD);
+    }
+
     Sema &S;
     Sema::AssociatedNamespaceSet &Namespaces;
     Sema::AssociatedClassSet &Classes;
@@ -2913,6 +2917,7 @@ namespace {
 
   private:
     Sema::AssociatedClassSet ClassesTransitive;
+    Sema::AssociatedClassSet ClassesWithVisitedTemplateArguments;
   };
 } // end anonymous namespace
 
@@ -3089,9 +3094,11 @@ addAssociatedClassesAndNamespaces(AssociatedLookup 
&Result,
     // Add the associated namespace for this class.
     CollectEnclosingNamespace(Result.Namespaces, Ctx);
 
-    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
-    for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
-      addAssociatedClassesAndNamespaces(Result, TemplateArgs[I]);
+    if (Result.visitTemplateArguments(Class)) {
+      const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+      for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
+        addAssociatedClassesAndNamespaces(Result, TemplateArgs[I]);
+    }
   }
 
   // Add the class itself. If we've already transitively visited this class,
diff --git a/clang/test/SemaCXX/adl-repeated-template-arguments.cpp 
b/clang/test/SemaCXX/adl-repeated-template-arguments.cpp
new file mode 100644
index 0000000000000..d29f748b4c8db
--- /dev/null
+++ b/clang/test/SemaCXX/adl-repeated-template-arguments.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+namespace assoc {
+struct Leaf {};
+template<class T, class U=T> struct Node {};
+void consume(...);
+}
+void 
test(assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Node<assoc::Leaf>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 value) { consume(value); }
+
+template<class T> struct Base {};
+namespace other { struct Tag {}; }
+struct Derived : Base<other::Tag> {};
+namespace other {
+constexpr int select(Derived, Base<Tag>) { return 7; }
+}
+static_assert(select(Derived{}, Base<other::Tag>{}) == 7);

``````````

</details>


https://github.com/llvm/llvm-project/pull/235714
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to