[Clang] prevent recovery call expression from proceeding with explicit attributes and undeclared templates (#107786)
Fixes #107047 Fixes #49093
This commit is contained in:
@@ -489,6 +489,8 @@ Bug Fixes to C++ Support
|
||||
- Clang now instantiates the correct lambda call operator when a lambda's class type is
|
||||
merged across modules. (#GH110401)
|
||||
- Fix a crash when parsing a pseudo destructor involving an invalid type. (#GH111460)
|
||||
- Fixed an assertion failure when invoking recovery call expressions with explicit attributes
|
||||
and undeclared templates. (#GH107047, #GH49093)
|
||||
|
||||
Bug Fixes to AST Handling
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -2470,7 +2470,15 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
|
||||
LookupCtx ? LookupCtx : (SS.isEmpty() ? CurContext : nullptr);
|
||||
while (DC) {
|
||||
if (isa<CXXRecordDecl>(DC)) {
|
||||
LookupQualifiedName(R, DC);
|
||||
if (ExplicitTemplateArgs) {
|
||||
if (LookupTemplateName(
|
||||
R, S, SS, Context.getRecordType(cast<CXXRecordDecl>(DC)),
|
||||
/*EnteringContext*/ false, TemplateNameIsRequired,
|
||||
/*RequiredTemplateKind*/ nullptr, /*AllowTypoCorrection*/ true))
|
||||
return true;
|
||||
} else {
|
||||
LookupQualifiedName(R, DC);
|
||||
}
|
||||
|
||||
if (!R.empty()) {
|
||||
// Don't give errors about ambiguities in this lookup.
|
||||
|
||||
32
clang/test/SemaTemplate/recovery-crash-cxx20.cpp
Normal file
32
clang/test/SemaTemplate/recovery-crash-cxx20.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
|
||||
|
||||
namespace GH49093 {
|
||||
class B {
|
||||
public:
|
||||
static int a() { return 0; } // expected-note {{declared as a non-template here}}
|
||||
decltype(a< 0 >(0)) test; // expected-error {{'a' does not refer to a template}}
|
||||
};
|
||||
|
||||
struct C {
|
||||
static int a() { return 0; } // expected-note {{declared as a non-template here}}
|
||||
decltype(a < 0 > (0)) test; // expected-error {{'a' does not refer to a template}}
|
||||
};
|
||||
|
||||
void test_is_bool(bool t) {}
|
||||
void test_is_bool(int t) {}
|
||||
|
||||
int main() {
|
||||
B b;
|
||||
test_is_bool(b.test);
|
||||
|
||||
C c;
|
||||
test_is_bool(c.test);
|
||||
}
|
||||
}
|
||||
|
||||
namespace GH107047 {
|
||||
struct A {
|
||||
static constexpr auto test() { return 1; } // expected-note {{declared as a non-template here}}
|
||||
static constexpr int s = test< 1 >(); // expected-error {{'test' does not refer to a template}}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user