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<T, T>`, 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
