diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index caca083409aa2c..c0019cfe4658d7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -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 ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 7401e4cc8f0928..e2141e03ca4230 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2470,7 +2470,15 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, LookupCtx ? LookupCtx : (SS.isEmpty() ? CurContext : nullptr); while (DC) { if (isa(DC)) { - LookupQualifiedName(R, DC); + if (ExplicitTemplateArgs) { + if (LookupTemplateName( + R, S, SS, Context.getRecordType(cast(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. diff --git a/clang/test/SemaTemplate/recovery-crash-cxx20.cpp b/clang/test/SemaTemplate/recovery-crash-cxx20.cpp new file mode 100644 index 00000000000000..e092ab802e459e --- /dev/null +++ b/clang/test/SemaTemplate/recovery-crash-cxx20.cpp @@ -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}} + }; +}