[clang] fce093c - [clang][Interp] Fix parameter map when re-visiting function

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 30 23:06:18 PDT 2023


Author: Timm Bäder
Date: 2023-03-31T08:06:06+02:00
New Revision: fce093ccb1c56b57bc26c47b47e2a0388953a27f

URL: https://github.com/llvm/llvm-project/commit/fce093ccb1c56b57bc26c47b47e2a0388953a27f
DIFF: https://github.com/llvm/llvm-project/commit/fce093ccb1c56b57bc26c47b47e2a0388953a27f.diff

LOG: [clang][Interp] Fix parameter map when re-visiting function

'Params' is a member of the ByteCodeEmitter. We only added the
parameters the first time  we saw the function, so subsequent visits
didn't work if they had (and used) parameters.

Just do the work everytime we see a function.

Differential Revision: https://reviews.llvm.org/D141681

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeEmitter.cpp
    clang/test/AST/Interp/functions.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
index 7453b60118ea..34ad9bf2b326 100644
--- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -22,51 +22,50 @@ using Error = llvm::Error;
 
 Expected<Function *>
 ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
-  // Create a handle over the emitted code.
-  Function *Func = P.getFunction(FuncDecl);
-  if (!Func) {
-    // Set up argument indices.
-    unsigned ParamOffset = 0;
-    SmallVector<PrimType, 8> ParamTypes;
-    llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors;
-
-    // If the return is not a primitive, a pointer to the storage where the
-    // value is initialized in is passed as the first argument. See 'RVO'
-    // elsewhere in the code.
-    QualType Ty = FuncDecl->getReturnType();
-    bool HasRVO = false;
-    if (!Ty->isVoidType() && !Ctx.classify(Ty)) {
-      HasRVO = true;
-      ParamTypes.push_back(PT_Ptr);
-      ParamOffset += align(primSize(PT_Ptr));
-    }
+  // Set up argument indices.
+  unsigned ParamOffset = 0;
+  SmallVector<PrimType, 8> ParamTypes;
+  llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors;
+
+  // If the return is not a primitive, a pointer to the storage where the
+  // value is initialized in is passed as the first argument. See 'RVO'
+  // elsewhere in the code.
+  QualType Ty = FuncDecl->getReturnType();
+  bool HasRVO = false;
+  if (!Ty->isVoidType() && !Ctx.classify(Ty)) {
+    HasRVO = true;
+    ParamTypes.push_back(PT_Ptr);
+    ParamOffset += align(primSize(PT_Ptr));
+  }
 
-    // If the function decl is a member decl, the next parameter is
-    // the 'this' pointer. This parameter is pop()ed from the
-    // InterpStack when calling the function.
-    bool HasThisPointer = false;
-    if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl);
-        MD && MD->isInstance()) {
-      HasThisPointer = true;
-      ParamTypes.push_back(PT_Ptr);
-      ParamOffset += align(primSize(PT_Ptr));
-    }
+  // If the function decl is a member decl, the next parameter is
+  // the 'this' pointer. This parameter is pop()ed from the
+  // InterpStack when calling the function.
+  bool HasThisPointer = false;
+  if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl);
+      MD && MD->isInstance()) {
+    HasThisPointer = true;
+    ParamTypes.push_back(PT_Ptr);
+    ParamOffset += align(primSize(PT_Ptr));
+  }
 
-    // Assign descriptors to all parameters.
-    // Composite objects are lowered to pointers.
-    for (const ParmVarDecl *PD : FuncDecl->parameters()) {
-      PrimType Ty = Ctx.classify(PD->getType()).value_or(PT_Ptr);
-      Descriptor *Desc = P.createDescriptor(PD, Ty);
-      ParamDescriptors.insert({ParamOffset, {Ty, Desc}});
-      Params.insert({PD, ParamOffset});
-      ParamOffset += align(primSize(Ty));
-      ParamTypes.push_back(Ty);
-    }
+  // Assign descriptors to all parameters.
+  // Composite objects are lowered to pointers.
+  for (const ParmVarDecl *PD : FuncDecl->parameters()) {
+    PrimType Ty = Ctx.classify(PD->getType()).value_or(PT_Ptr);
+    Descriptor *Desc = P.createDescriptor(PD, Ty);
+    ParamDescriptors.insert({ParamOffset, {Ty, Desc}});
+    Params.insert({PD, ParamOffset});
+    ParamOffset += align(primSize(Ty));
+    ParamTypes.push_back(Ty);
+  }
 
+  // Create a handle over the emitted code.
+  Function *Func = P.getFunction(FuncDecl);
+  if (!Func)
     Func =
         P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes),
                          std::move(ParamDescriptors), HasThisPointer, HasRVO);
-  }
 
   assert(Func);
   // For not-yet-defined functions, we only create a Function instance and

diff  --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp
index 5113593d8d11..1abdb2db97ff 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -180,3 +180,8 @@ struct BodylessMemberFunction {
     return 1;
   }
 };
+
+constexpr int nyd(int m);
+constexpr int doit() { return nyd(10); }
+constexpr int nyd(int m) { return m; }
+static_assert(doit() == 10);


        


More information about the cfe-commits mailing list