Skip to content

Commit 55bbcbf

Browse files
committed
[clang] Reset track of immediate function context when entering new function
Due to not resetting that, clang still thinks that it is in immediate function context even if it already entered non-consteval function. This caused consteval functions reaching codegen in some cases. Fixes #61142 Reviewed By: cor3ntin, aaron.ballman Differential Revision: https://reviews.llvm.org/D147531
1 parent 93fb1ba commit 55bbcbf

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ Bug Fixes in This Version
279279
- Fix crash when generating code coverage information for `PseudoObjectExpr` in
280280
Clang AST.
281281
(`#45481 <https://github.com/llvm/llvm-project/issues/45481>`_)
282+
- Fix the assertion hit when a template consteval function appears in a nested
283+
consteval/constexpr call chain.
284+
(`#61142 <https://github.com/llvm/llvm-project/issues/61142>`_)
282285

283286
Bug Fixes to Compiler Builtins
284287
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaDecl.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15180,6 +15180,15 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
1518015180
FD->isConsteval() ? ExpressionEvaluationContext::ImmediateFunctionContext
1518115181
: ExprEvalContexts.back().Context);
1518215182

15183+
// Each ExpressionEvaluationContextRecord also keeps track of whether the
15184+
// context is nested in an immediate function context, so smaller contexts
15185+
// that appear inside immediate functions (like variable initializers) are
15186+
// considered to be inside an immediate function context even though by
15187+
// themselves they are not immediate function contexts. But when a new
15188+
// function is entered, we need to reset this tracking, since the entered
15189+
// function might be not an immediate function.
15190+
ExprEvalContexts.back().InImmediateFunctionContext = FD->isConsteval();
15191+
1518315192
// Check for defining attributes before the check for redefinition.
1518415193
if (const auto *Attr = FD->getAttr<AliasAttr>()) {
1518515194
Diag(Attr->getLocation(), diag::err_alias_is_definition) << FD << 0;

clang/test/CodeGenCXX/cxx20-consteval-crash.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,27 @@ void method() {
116116
}
117117

118118
} // namespace GH60166
119+
120+
namespace GH61142 {
121+
122+
template <typename T>
123+
struct Test {
124+
constexpr static void bar() {
125+
foo();
126+
}
127+
consteval static void foo() {};
128+
};
129+
130+
consteval void a() {
131+
Test<int>::bar();
132+
}
133+
134+
void b() {
135+
Test<int>::bar();
136+
}
137+
138+
// Make sure consteval function is not emitted.
139+
// CHECK-NOT: call {{.*}}foo{{.*}}()
140+
// CHECK-NOT: define {{.*}}foo{{.*}}()
141+
142+
} // namespace GH61142

0 commit comments

Comments
 (0)