Skip to content

Commit

Permalink
[clang][Interp] Remove args from called functions in more cases
Browse files Browse the repository at this point in the history
When calling functions in the checkingPotentialConstantExpression mode,
we cannot have arguments (including This + RVO pointers) for the
toplevel callee, but the functions called from within can work just
fine, or at least we succeed in pushing their arguments on the stack, so
we must also succeed in removing them again.

Differential Revision: https://reviews.llvm.org/D150358
  • Loading branch information
tbaederr committed Jul 26, 2023
1 parent 6d2e141 commit 8a4bbeb
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 8 deletions.
8 changes: 3 additions & 5 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,12 @@ enum class ArithOp { Add, Sub };
// Returning values
//===----------------------------------------------------------------------===//

template <PrimType Name, bool Builtin = false,
class T = typename PrimConv<Name>::T>
template <PrimType Name, class T = typename PrimConv<Name>::T>
bool Ret(InterpState &S, CodePtr &PC, APValue &Result) {
const T &Ret = S.Stk.pop<T>();

assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
if (Builtin || !S.checkingPotentialConstantExpression())
if (!S.checkingPotentialConstantExpression() || S.Current->Caller)
S.Current->popArgs();

if (InterpFrame *Caller = S.Current->Caller) {
Expand All @@ -200,10 +199,9 @@ bool Ret(InterpState &S, CodePtr &PC, APValue &Result) {
return true;
}

template <bool Builtin = false>
inline bool RetVoid(InterpState &S, CodePtr &PC, APValue &Result) {
assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
if (Builtin || !S.checkingPotentialConstantExpression())
if (!S.checkingPotentialConstantExpression() || S.Current->Caller)
S.Current->popArgs();

if (InterpFrame *Caller = S.Current->Caller) {
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/AST/Interp/InterpBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) {
switch (F->getBuiltinID()) {
case Builtin::BI__builtin_is_constant_evaluated:
S.Stk.push<Boolean>(Boolean::from(S.inConstantContext()));
return Ret<PT_Bool, true>(S, OpPC, Dummy);
return Ret<PT_Bool>(S, OpPC, Dummy);
case Builtin::BI__builtin_assume:
return RetVoid<true>(S, OpPC, Dummy);
return RetVoid(S, OpPC, Dummy);
case Builtin::BI__builtin_strcmp:
if (interp__builtin_strcmp(S, OpPC, Frame))
return Ret<PT_Sint32, true>(S, OpPC, Dummy);
return Ret<PT_Sint32>(S, OpPC, Dummy);
return false;
default:
return false;
Expand Down
8 changes: 8 additions & 0 deletions clang/test/AST/Interp/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,11 @@ namespace InvalidCall {
// ref-note {{in call to 'SS()'}}

}

namespace CallWithArgs {
/// This used to call problems during checkPotentialConstantExpression() runs.
constexpr void g(int a) {}
constexpr void f() {
g(0);
}
}

0 comments on commit 8a4bbeb

Please sign in to comment.