Author: Timm Bäder Date: 2023-07-26T08:47:54+02:00 New Revision: 8a4bbeb9168cec7d7bec7b21f4718c58dcff7602
URL: https://github.com/llvm/llvm-project/commit/8a4bbeb9168cec7d7bec7b21f4718c58dcff7602 DIFF: https://github.com/llvm/llvm-project/commit/8a4bbeb9168cec7d7bec7b21f4718c58dcff7602.diff LOG: [clang][Interp] Remove args from called functions in more cases 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 Added: Modified: clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/InterpBuiltin.cpp clang/test/AST/Interp/functions.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 38caee0e7a6094..87bcf8130a73b3 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -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) { @@ -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) { diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index c11f22aa94cacf..0d0859a4cd284b 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -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; diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 5bb48ffc54dd5a..629d0323e1d2e8 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -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); + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits