Author: Alejandro Álvarez Ayllón Date: 2024-07-19T11:00:30+02:00 New Revision: e5df657bbf38f8fcd9dd8c9e79262ca184f2598b
URL: https://github.com/llvm/llvm-project/commit/e5df657bbf38f8fcd9dd8c9e79262ca184f2598b DIFF: https://github.com/llvm/llvm-project/commit/e5df657bbf38f8fcd9dd8c9e79262ca184f2598b.diff LOG: [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`. Added: clang/test/SemaCXX/instantiate-template-broken-nontype-default.cpp Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaTemplateInstantiateDecl.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b0afadfa8d324..4efdb076ba768 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 01432301633ed..97161febc15f7 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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(); diff --git a/clang/test/SemaCXX/instantiate-template-broken-nontype-default.cpp b/clang/test/SemaCXX/instantiate-template-broken-nontype-default.cpp new file mode 100644 index 0000000000000..eb798e5887bda --- /dev/null +++ b/clang/test/SemaCXX/instantiate-template-broken-nontype-default.cpp @@ -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'}} + _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits