Skip to content

Commit

Permalink
[Sema] Fix assertion error in Sema::FindInstantiatedDecl (#96509)
Browse files Browse the repository at this point in the history
...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`.
  • Loading branch information
alejandro-alvarez-sonarsource authored Jul 19, 2024
1 parent f0617d2 commit e5df657
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 1 deletion.
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
7 changes: 6 additions & 1 deletion clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
14 changes: 14 additions & 0 deletions clang/test/SemaCXX/instantiate-template-broken-nontype-default.cpp
Original file line number Diff line number Diff line change
@@ -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'}}

0 comments on commit e5df657

Please sign in to comment.