[Sema] Fix assertion error in Sema::FindInstantiatedDecl (#96509)

...when looking for a template instantiation with a non-type parameter of
unknown type and with a default value.

This can happen when a template non-type parameter has a broken
expression that gets replaced by a `RecoveryExpr`.
This commit is contained in:
Alejandro Álvarez Ayllón 2024-07-19 11:00:30 +02:00 committed by GitHub
parent f0617d2def
commit e5df657bbf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 1 deletions

View File

@ -857,6 +857,9 @@ Bug Fixes in This Version
- ``typeof_unqual`` now properly removes type qualifiers from arrays and their element types. (#GH92667)
- Fixed an assertion failure when a template non-type parameter contains
an invalid expression.
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -6229,7 +6229,12 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
getTrivialTemplateArgumentLoc(UnpackedArg, QualType(), Loc));
}
QualType T = CheckTemplateIdType(TemplateName(TD), Loc, Args);
if (T.isNull())
// We may get a non-null type with errors, in which case
// `getAsCXXRecordDecl` will return `nullptr`. For instance, this
// happens when one of the template arguments is an invalid
// expression. We return early to avoid triggering the assertion
// about the `CodeSynthesisContext`.
if (T.isNull() || T->containsErrors())
return nullptr;
CXXRecordDecl *SubstRecord = T->getAsCXXRecordDecl();

View File

@ -0,0 +1,14 @@
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
constexpr Missing a = 0; // expected-error {{unknown type name 'Missing'}}
template < typename T, Missing b = a> // expected-error {{unknown type name 'Missing'}}
class Klass { // expected-note {{candidate template ignored: could not match 'Klass<T, b>' against 'int'}} \
expected-note {{implicit deduction guide declared as 'template <typename T, int b = <recovery-expr>()> Klass(Klass<T, b>) -> Klass<T, b>'}}
Klass(T); // expected-note {{candidate template ignored: substitution failure [with T = int, b = <recovery-expr>()]}} \
expected-note {{implicit deduction guide declared as 'template <typename T, int b = <recovery-expr>()> Klass(T) -> Klass<T, b>'}}
};
Klass foo{5}; // no-crash \
expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'Klass'}}