[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
Tue Mar 5 05:39:12 PST 2024
https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/83842
>From 4725321631e69c8d8480e0dba85128d177541a89 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 1/5] [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 3ae78748a4e499..9fc7765dc8ec27 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}}
>From 5420f85f10af006c9acb3d28288373b1c000c9c3 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Mon, 4 Mar 2024 11:58:17 -0500
Subject: [PATCH 2/5] [FOLD] assume names is template when any function is
found
---
clang/lib/AST/ASTContext.cpp | 3 +--
clang/lib/Sema/SemaDecl.cpp | 7 +++++--
clang/lib/Sema/SemaTemplate.cpp | 10 ++++++----
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 28dd69b8e45758..5a8fae76a43a4d 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -9200,8 +9200,7 @@ TemplateName
ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
UnresolvedSetIterator End) const {
unsigned size = End - Begin;
- assert((size == 1 && isa<UnresolvedUsingValueDecl>(*Begin)) ||
- size > 1 && "set is not overloaded!");
+ assert(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 9fc7765dc8ec27..4b46b357aca93a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1110,17 +1110,20 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
// unqualified-id followed by a < and name lookup finds either one
// or more functions or finds nothing.
if (!IsFilteredTemplateName)
- FilterAcceptableTemplateNames(Result);
+ FilterAcceptableTemplateNames(Result,
+ /*AllowFunctionTemplates=*/true,
+ /*AllowDependent=*/true);
bool IsFunctionTemplate;
bool IsVarTemplate;
TemplateName Template;
- if ((Result.end() - Result.begin() > 1) || Result.isUnresolvableResult()) {
+ if (Result.end() - Result.begin() > 1) {
IsFunctionTemplate = true;
Template = Context.getOverloadedTemplateName(Result.begin(),
Result.end());
} else if (!Result.empty()) {
+ assert(!Result.isUnresolvableResult());
auto *TD = cast<TemplateDecl>(getAsTemplateNameDecl(
*Result.begin(), /*AllowFunctionTemplates=*/true,
/*AllowDependent=*/false));
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 873ea10ebe0660..df20f83ac8afe6 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -491,18 +491,20 @@ bool Sema::LookupTemplateName(LookupResult &Found,
// To keep our behavior consistent, we apply the "finds nothing" part in
// all language modes, and diagnose the empty lookup in ActOnCallExpr if we
// successfully form a call to an undeclared template-id.
- bool AllFunctions =
- getLangOpts().CPlusPlus20 && llvm::all_of(Found, [](NamedDecl *ND) {
+ bool AnyFunctions =
+ getLangOpts().CPlusPlus20 && llvm::any_of(Found, [](NamedDecl *ND) {
return isa<FunctionDecl>(ND->getUnderlyingDecl());
});
- if (AllFunctions || (Found.empty() && !IsDependent)) {
+ if (AnyFunctions || (Found.empty() && !IsDependent)) {
// If lookup found any functions, or if this is a name that can only be
// used for a function, then strongly assume this is a function
// template-id.
*ATK = (Found.empty() && Found.getLookupName().isIdentifier())
? AssumedTemplateKind::FoundNothing
: AssumedTemplateKind::FoundFunctions;
- Found.clear();
+ FilterAcceptableTemplateNames(Found,
+ /*AllowFunctionTemplates*/ true,
+ /*AllowDependent*/ true);
return false;
}
}
>From 6b93befa40d3f0ac41de9176a75babebf7468d71 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Mon, 4 Mar 2024 13:10:21 -0500
Subject: [PATCH 3/5] [FOLD] add release note
---
clang/docs/ReleaseNotes.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c328ae18c024ce..de5f339cc7f0ba 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -305,6 +305,8 @@ Bug Fixes to C++ Support
our attention by an attempt to fix in (#GH77703). Fixes (#GH83385).
- Fix evaluation of some immediate calls in default arguments.
Fixes (#GH80630)
+- Fix a crash when an explicit template argument list is used with a name for which lookup
+ finds a non-template function and a dependent using declarator.
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
>From 5d4191c3930b1a6afdc8740473e5cb8f42ba5838 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 5 Mar 2024 08:30:38 -0500
Subject: [PATCH 4/5] [FOLD] remove newline
---
clang/lib/Sema/SemaDecl.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4b46b357aca93a..8fcaf6ab312b04 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1117,7 +1117,6 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
bool IsFunctionTemplate;
bool IsVarTemplate;
TemplateName Template;
-
if (Result.end() - Result.begin() > 1) {
IsFunctionTemplate = true;
Template = Context.getOverloadedTemplateName(Result.begin(),
>From ce1e5a979e7ee3c1b3e1bbc5254524c39815c8e1 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 5 Mar 2024 08:38:58 -0500
Subject: [PATCH 5/5] [FOLD] update test
---
.../SemaTemplate/unqual-unresolved-using-value.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/clang/test/SemaTemplate/unqual-unresolved-using-value.cpp b/clang/test/SemaTemplate/unqual-unresolved-using-value.cpp
index 7c45342adce783..688e7a0a10b779 100644
--- a/clang/test/SemaTemplate/unqual-unresolved-using-value.cpp
+++ b/clang/test/SemaTemplate/unqual-unresolved-using-value.cpp
@@ -4,13 +4,16 @@ template<typename T>
struct A : T {
using T::f;
using T::g;
+ using T::h;
void f();
void g();
- void h() {
+ void i() {
f<int>();
g<int>(); // expected-error{{no member named 'g' in 'A<B>'}}
+ h<int>(); // expected-error{{expected '(' for function-style cast or type construction}}
+ // expected-error at -1{{expected expression}}
}
};
@@ -19,6 +22,9 @@ struct B {
void f();
void g();
+
+ template<typename T>
+ void h();
};
-template struct A<B>; // expected-note{{in instantiation of member function 'A<B>::h' requested here}}
+template struct A<B>; // expected-note{{in instantiation of member function 'A<B>::i' requested here}}
More information about the cfe-commits
mailing list