[clang] [clang][Interp] Handle variadic functions (PR #67814)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 23 05:52:23 PDT 2023


================
@@ -121,18 +121,47 @@ static bool CheckGlobal(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
 
 namespace clang {
 namespace interp {
+static void popArg(InterpState &S, const Expr *Arg) {
+  PrimType Ty = S.getContext().classify(Arg->getType()).value_or(PT_Ptr);
+  TYPE_SWITCH(Ty, S.Stk.discard<T>());
+}
+
+void cleanupAfterFunctionCall(InterpState &S, CodePtr OpPC) {
+  assert(S.Current);
+  const Function *CurFunc = S.Current->getFunction();
+  assert(CurFunc);
+
+  // Certain builtin functions are declared as func-name(...), so the
+  // parameters are checked in Sema and only available through the CallExpr.
+  // The interp::Function we create for them has 0 parameters, so we need to
+  // remove them from the stack by checking the CallExpr.
+  // FIXME: This is potentially just a special case and could be handled more
+  // generally with the code just below?
+  if (CurFunc->needsRuntimeArgPop(S.getCtx())) {
+    const CallExpr *CE = cast<CallExpr>(S.Current->getExpr(OpPC));
+    for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
+      popArg(S, CE->getArg(I));
+    }
+    return;
+  }
 
-bool popBuiltinArgs(InterpState &S, CodePtr OpPC) {
-  assert(S.Current && S.Current->getFunction()->needsRuntimeArgPop(S.getCtx()));
-  const Expr *E = S.Current->getExpr(OpPC);
-  assert(isa<CallExpr>(E));
-  const CallExpr *CE = cast<CallExpr>(E);
-  for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
-    const Expr *A = CE->getArg(I);
-    PrimType Ty = S.getContext().classify(A->getType()).value_or(PT_Ptr);
-    TYPE_SWITCH(Ty, S.Stk.discard<T>());
+  if (S.Current->Caller && CurFunc->isVariadic()) {
+    // CallExpr we're look for is at the return PC of the current function, i.e.
+    // in the caller.
+    // This code path should be executed very rarely.
+    const CallExpr *CE =
+        cast<CallExpr>(S.Current->Caller->getExpr(S.Current->getRetPC()));
----------------
AaronBallman wrote:

```suggestion
    const auto *CE =
        cast<CallExpr>(S.Current->Caller->getExpr(S.Current->getRetPC()));
```

https://github.com/llvm/llvm-project/pull/67814


More information about the cfe-commits mailing list