https://github.com/firstmoonlight updated 
https://github.com/llvm/llvm-project/pull/190322

>From d45dc81e1e4a45c1d3c2d30888d5dca400013157 Mon Sep 17 00:00:00 2001
From: victorl <[email protected]>
Date: Fri, 3 Apr 2026 16:10:18 +0800
Subject: [PATCH] [clang][Sema] fix Crash in clang::Sema::ClassifyName when
 calling overloaded using declarations

---
 clang/lib/Sema/SemaDecl.cpp                   | 44 +++++++++++--------
 .../SemaTemplate/lookup-dependent-using.cpp   | 33 ++++++++++++++
 2 files changed, 58 insertions(+), 19 deletions(-)
 create mode 100644 clang/test/SemaTemplate/lookup-dependent-using.cpp

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2951fd09294d8..498bfc25124cf 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1156,26 +1156,32 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, 
CXXScopeSpec &SS,
       IsFunctionTemplate = true;
       Template = Context.getOverloadedTemplateName(Result.begin(),
                                                    Result.end());
-    } else if (!Result.empty()) {
-      auto *TD = cast<TemplateDecl>(getAsTemplateNameDecl(
-          *Result.begin(), /*AllowFunctionTemplates=*/true,
-          /*AllowDependent=*/false));
-      IsFunctionTemplate = isa<FunctionTemplateDecl>(TD);
-      IsVarTemplate = isa<VarTemplateDecl>(TD);
-
-      UsingShadowDecl *FoundUsingShadow =
-          dyn_cast<UsingShadowDecl>(*Result.begin());
-      assert(!FoundUsingShadow ||
-             TD == cast<TemplateDecl>(FoundUsingShadow->getTargetDecl()));
-      Template = Context.getQualifiedTemplateName(
-          SS.getScopeRep(),
-          /*TemplateKeyword=*/false,
-          FoundUsingShadow ? TemplateName(FoundUsingShadow) : 
TemplateName(TD));
     } else {
-      // All results were non-template functions. This is a function template
-      // name.
-      IsFunctionTemplate = true;
-      Template = Context.getAssumedTemplateName(NameInfo.getName());
+      TemplateDecl *TD = nullptr;
+      if (!Result.empty()) {
+        TD = dyn_cast_or_null<TemplateDecl>(getAsTemplateNameDecl(
+            *Result.begin(), /*AllowFunctionTemplates=*/true,
+            /*AllowDependent=*/false));
+      }
+
+      if (TD) {
+        IsFunctionTemplate = isa<FunctionTemplateDecl>(TD);
+        IsVarTemplate = isa<VarTemplateDecl>(TD);
+
+        UsingShadowDecl *FoundUsingShadow =
+            dyn_cast<UsingShadowDecl>(*Result.begin());
+        assert(!FoundUsingShadow ||
+              TD == cast<TemplateDecl>(FoundUsingShadow->getTargetDecl()));
+        Template = Context.getQualifiedTemplateName(
+            SS.getScopeRep(),
+            /*TemplateKeyword=*/false,
+            FoundUsingShadow ? TemplateName(FoundUsingShadow) : 
TemplateName(TD));
+      } else {
+        // All results were non-template functions. This is a function template
+        // name.
+        IsFunctionTemplate = true;
+        Template = Context.getAssumedTemplateName(NameInfo.getName());
+      }
     }
 
     if (IsFunctionTemplate) {
diff --git a/clang/test/SemaTemplate/lookup-dependent-using.cpp 
b/clang/test/SemaTemplate/lookup-dependent-using.cpp
new file mode 100644
index 0000000000000..1dc0ba7ad29f3
--- /dev/null
+++ b/clang/test/SemaTemplate/lookup-dependent-using.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+// expected-no-diagnostics
+
+// This is a regression test that verifies handling a mix of using-declarations
+// from dependent and non-dependent base classes does not cause name lookup
+// to crash when a dependent entity cannot be converted to a TemplateDecl.
+
+template<typename A>
+class X {
+public:
+    template<typename T>
+    void execute(int a) {}
+};
+
+class Y {
+public:
+    void execute(int a) {}
+};
+
+template<typename A>
+class Exec : public X<A>, public Y {
+public:
+    using X<A>::execute;
+    using Y::execute;
+    
+    void validate() {
+        // In C++20 the 'execute' here is followed by '<'.
+        // The lookup result will include an UnresolvedUsingValueDecl (from 
X<A>)
+        // and a UsingShadowDecl (from Y).
+        execute<int>(42); 
+        execute(42);
+    }
+};

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

Reply via email to