llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: firstmoonlight <details> <summary>Changes</summary> The code in Sema::ClassifyName (or relevant template lookup logic) used a hard `cast<TemplateDecl>`, which caused a crash when encountering an `UnresolvedUsingValueDecl` (e.g., a `using` declaration pointing to a dependent base class member). This patch: 1. Replaces the unsafe `cast` with `dyn_cast_or_null`. 2. Adds a fallback path to construct an `AssumedTemplateName` or `DependentTemplateName` when a concrete `TemplateDecl` is not immediately available. Fixes: https://github.com/llvm/llvm-project/issues/174951 --- Full diff: https://github.com/llvm/llvm-project/pull/190322.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaDecl.cpp (+25-19) - (added) clang/test/SemaTemplate/lookup-dependent-using.cpp (+33) ``````````diff diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a479ff68c35c5..bb867ef192bab 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1157,26 +1157,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); + } +}; `````````` </details> https://github.com/llvm/llvm-project/pull/190322 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
