[clang] [Clang][Sema] Fix crash when using name of UnresolvedUsingValueDecl with template arguments (PR #83842)
Krystian Stasiowski via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 4 05:38:18 PST 2024
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 <sdkrystian at 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}}
More information about the cfe-commits
mailing list