From: Timm Bäder Date: Mon, 10 Oct 2022 11:18:12 +0000 (+0200) Subject: [clang][Interp][NFC] Add assertions to VM entry points X-Git-Tag: upstream/17.0.6~29836 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c01ac372fc3308e4c6c31361e44e604410cd1573;p=platform%2Fupstream%2Fllvm.git [clang][Interp][NFC] Add assertions to VM entry points Assert that the previous call left the stack empty, as well as that successful interpretations leave an empty stack. --- diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp index a43ced4..495d019 100644 --- a/clang/lib/AST/Interp/Context.cpp +++ b/clang/lib/AST/Interp/Context.cpp @@ -27,6 +27,7 @@ Context::Context(ASTContext &Ctx) : Ctx(Ctx), P(new Program(*this)) {} Context::~Context() {} bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { + assert(Stk.empty()); Function *Func = P->getFunction(FD); if (!Func) { if (auto R = ByteCodeStmtGen(*this, *P).compileFunc(FD)) { @@ -45,14 +46,28 @@ bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { } bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) { + assert(Stk.empty()); ByteCodeExprGen C(*this, *P, Parent, Stk, Result); - return Check(Parent, C.interpretExpr(E)); + if (Check(Parent, C.interpretExpr(E))) { + assert(Stk.empty()); + return true; + } + + Stk.clear(); + return false; } bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result) { + assert(Stk.empty()); ByteCodeExprGen C(*this, *P, Parent, Stk, Result); - return Check(Parent, C.interpretDecl(VD)); + if (Check(Parent, C.interpretDecl(VD))) { + assert(Stk.empty()); + return true; + } + + Stk.clear(); + return false; } const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); } diff --git a/clang/lib/AST/Interp/InterpStack.h b/clang/lib/AST/Interp/InterpStack.h index 7c338aa..3adaad9 100644 --- a/clang/lib/AST/Interp/InterpStack.h +++ b/clang/lib/AST/Interp/InterpStack.h @@ -75,6 +75,9 @@ public: /// Clears the stack without calling any destructors. void clear(); + // Returns whether the stack is empty. + bool empty() const { return StackSize == 0; } + private: /// All stack slots are aligned to the native pointer alignment for storage. /// The size of an object is rounded up to a pointer alignment multiple.