diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -279,6 +279,9 @@ - Fix crash when generating code coverage information for `PseudoObjectExpr` in Clang AST. (`#45481 `_) +- Fix the assertion hit when a template consteval function appears in a nested + consteval/constexpr call chain. + (`#61142 `_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15180,6 +15180,15 @@ FD->isConsteval() ? ExpressionEvaluationContext::ImmediateFunctionContext : ExprEvalContexts.back().Context); + // Each ExpressionEvaluationContextRecord also keeps track of whether the + // context is nested in an immediate function context, so smaller contexts + // that appear inside immediate functions (like variable initializers) are + // considered to be inside an immediate function context even though by + // themselves they are not immediate function contexts. But when a new + // function is entered, we need to reset this tracking, since the entered + // function might be not an immediate function. + ExprEvalContexts.back().InImmediateFunctionContext = FD->isConsteval(); + // Check for defining attributes before the check for redefinition. if (const auto *Attr = FD->getAttr()) { Diag(Attr->getLocation(), diag::err_alias_is_definition) << FD << 0; diff --git a/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp b/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp --- a/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp +++ b/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp @@ -116,3 +116,27 @@ } } // namespace GH60166 + +namespace GH61142 { + +template +struct Test { + constexpr static void bar() { + foo(); + } + consteval static void foo() {}; +}; + +consteval void a() { + Test::bar(); +} + +void b() { + Test::bar(); +} + +// Make sure consteval function is not emitted. +// CHECK-NOT: call {{.*}}foo{{.*}}() +// CHECK-NOT: define {{.*}}foo{{.*}}() + +} // namespace GH61142