[clang] [clang][bytecode] Remove the !Caller case in Ret opcodes (PR #215226)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 10 02:25:21 PDT 2026
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/215226
The bottom frame is always created via an `EvalEmitter`, which has its own implementation of the `Ret` opcode. The exception is `Context::Run`/`isPotentialConstantExpr`.
>From 1157fff92e4ffb2844a91f02088e5b0d8b5fd8cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 10 Aug 2026 11:23:03 +0200
Subject: [PATCH] [clang][bytecode] Remove the !Caller case in Ret opcodes
---
clang/lib/AST/ByteCode/Context.cpp | 2 +-
clang/lib/AST/ByteCode/Interp.h | 35 ++++++++++++++----------------
2 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp
index 9f1d9b899052d..ce7a95ed49c06 100644
--- a/clang/lib/AST/ByteCode/Context.cpp
+++ b/clang/lib/AST/ByteCode/Context.cpp
@@ -555,8 +555,8 @@ const llvm::fltSemantics &Context::getFloatSemantics(QualType T) const {
}
bool Context::Run(State &Parent, const Function *Func) {
- InterpState State(Parent, *P, Stk, *this, Func);
auto Memory = std::make_unique<char[]>(InterpFrame::allocSize(Func));
+ InterpState State(Parent, *P, Stk, *this, Func);
InterpFrame *Frame = new (Memory.get()) InterpFrame(
State, Func, /*Caller=*/nullptr, CodePtr(), Func->getArgSize());
State.Current = Frame;
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 582cb108f5816..0af1610181aac 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -298,18 +298,16 @@ PRESERVE_NONE bool Ret(InterpState &S) {
if (!S.checkingPotentialConstantExpression() || S.Current->Caller)
cleanupAfterFunctionCall(S, S.Current->getFunction());
- if (InterpFrame *Caller = S.Current->Caller) {
- S.PC = S.Current->getRetPC();
- InterpFrame::free(S.Current);
- S.Current = Caller;
- S.Stk.push<T>(Ret);
- } else {
- InterpFrame::free(S.Current);
- S.Current = nullptr;
- // The topmost frame should come from an EvalEmitter,
- // which has its own implementation of the Ret<> instruction.
- }
+ InterpFrame *Caller = S.Current->Caller;
+
+ // This only happens via Context::Run().
+ if (!Caller)
+ return true;
+ S.PC = S.Current->getRetPC();
+ InterpFrame::free(S.Current);
+ S.Current = Caller;
+ S.Stk.push<T>(Ret);
return true;
}
@@ -321,15 +319,14 @@ PRESERVE_NONE inline bool RetVoid(InterpState &S) {
if (!S.checkingPotentialConstantExpression() || S.Current->Caller)
cleanupAfterFunctionCall(S, S.Current->getFunction());
- if (InterpFrame *Caller = S.Current->Caller) {
- S.PC = S.Current->getRetPC();
- InterpFrame::free(S.Current);
- S.Current = Caller;
- } else {
- InterpFrame::free(S.Current);
- S.Current = nullptr;
- }
+ InterpFrame *Caller = S.Current->Caller;
+ // This only happens via Context::Run().
+ if (!Caller)
+ return true;
+ S.PC = S.Current->getRetPC();
+ InterpFrame::free(S.Current);
+ S.Current = Caller;
return true;
}
More information about the cfe-commits
mailing list