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

via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 19 02:00:33 PDT 2024


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'}}
+


        


More information about the cfe-commits mailing list