https://github.com/sdkrystian created https://github.com/llvm/llvm-project/pull/83842
The following snippet causes a crash ([godbolt link](https://godbolt.org/z/E17sYfYrY)): ```cpp template<typename T> struct A : T { using T::f; void f(); void g() { f<int>(); // crash here } }; ``` This happens because we cast the result of `getAsTemplateNameDecl` as a `TemplateDecl` in `Sema::ClassifyName`, which we cannot do for an `UnresolvedUsingValueDecl`. I believe the correct thing to do here is to create an `OverloadedTemplateName`. >From aeeb445a9e52a8011a008a5ee3438709f835034c Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Mon, 4 Mar 2024 08:10:35 -0500 Subject: [PATCH] [Clang][Sema] Fix crash when using name of UnresolvedUsingValueDecl with template arguments --- clang/lib/AST/ASTContext.cpp | 3 ++- clang/lib/Sema/SemaDecl.cpp | 3 ++- .../unqual-unresolved-using-value.cpp | 24 +++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaTemplate/unqual-unresolved-using-value.cpp diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 5a8fae76a43a4d..28dd69b8e45758 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -9200,7 +9200,8 @@ TemplateName ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin, UnresolvedSetIterator End) const { unsigned size = End - Begin; - assert(size > 1 && "set is not overloaded!"); + assert((size == 1 && isa<UnresolvedUsingValueDecl>(*Begin)) || + size > 1 && "set is not overloaded!"); void *memory = Allocate(sizeof(OverloadedTemplateStorage) + size * sizeof(FunctionTemplateDecl*)); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9fdd8eb236d1ee..c62e4ce7d0f9c4 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1115,7 +1115,8 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, bool IsFunctionTemplate; bool IsVarTemplate; TemplateName Template; - if (Result.end() - Result.begin() > 1) { + + if ((Result.end() - Result.begin() > 1) || Result.isUnresolvableResult()) { IsFunctionTemplate = true; Template = Context.getOverloadedTemplateName(Result.begin(), Result.end()); diff --git a/clang/test/SemaTemplate/unqual-unresolved-using-value.cpp b/clang/test/SemaTemplate/unqual-unresolved-using-value.cpp new file mode 100644 index 00000000000000..7c45342adce783 --- /dev/null +++ b/clang/test/SemaTemplate/unqual-unresolved-using-value.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s + +template<typename T> +struct A : T { + using T::f; + using T::g; + + void f(); + void g(); + + void h() { + f<int>(); + g<int>(); // expected-error{{no member named 'g' in 'A<B>'}} + } +}; + +struct B { + template<typename T> + void f(); + + void g(); +}; + +template struct A<B>; // expected-note{{in instantiation of member function 'A<B>::h' requested here}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits