[clang] 89361e2 - [clang][Interp] Fix passing parameters of composite type

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 17 03:08:26 PDT 2023


Author: Timm Bäder
Date: 2023-08-17T12:08:10+02:00
New Revision: 89361e2b98a9ce355bdde0ae02425ecbe5f9c06d

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

LOG: [clang][Interp] Fix passing parameters of composite type

We pass these as pointers, so we need to be careful not to emit pointers
to pointers when we emit visit DeclRefExprs pointing to parameters.

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

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeEmitter.cpp
    clang/lib/AST/Interp/ByteCodeEmitter.h
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/lib/AST/Interp/ByteCodeStmtGen.cpp
    clang/lib/AST/Interp/Context.h
    clang/lib/AST/Interp/EvalEmitter.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
index c33c9bd37e031c..ba0668ed9c940b 100644
--- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -74,13 +74,14 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
   // 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});
+    std::optional<PrimType> T = Ctx.classify(PD->getType());
+    PrimType PT = T.value_or(PT_Ptr);
+    Descriptor *Desc = P.createDescriptor(PD, PT);
+    ParamDescriptors.insert({ParamOffset, {PT, Desc}});
+    Params.insert({PD, {ParamOffset, T != std::nullopt}});
     ParamOffsets.push_back(ParamOffset);
-    ParamOffset += align(primSize(Ty));
-    ParamTypes.push_back(Ty);
+    ParamOffset += align(primSize(PT));
+    ParamTypes.push_back(PT);
   }
 
   // Create a handle over the emitted code.

diff  --git a/clang/lib/AST/Interp/ByteCodeEmitter.h b/clang/lib/AST/Interp/ByteCodeEmitter.h
index 795534696d92ff..c917622a1864fa 100644
--- a/clang/lib/AST/Interp/ByteCodeEmitter.h
+++ b/clang/lib/AST/Interp/ByteCodeEmitter.h
@@ -69,10 +69,9 @@ class ByteCodeEmitter {
   Local createLocal(Descriptor *D);
 
   /// Parameter indices.
-  llvm::DenseMap<const ParmVarDecl *, unsigned> Params;
+  llvm::DenseMap<const ParmVarDecl *, ParamOffset> Params;
   /// Lambda captures.
-  /// Map from Decl* to [Offset, IsReference] pair.
-  llvm::DenseMap<const ValueDecl *, std::pair<unsigned, bool>> LambdaCaptures;
+  llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures;
   unsigned LambdaThisCapture;
   /// Local descriptors.
   llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 77d2b1131005d1..f9a7cf7b743ef0 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1195,7 +1195,7 @@ bool ByteCodeExprGen<Emitter>::dereferenceParam(
     llvm::function_ref<bool(PrimType)> Indirect) {
   auto It = this->Params.find(PD);
   if (It != this->Params.end()) {
-    unsigned Idx = It->second;
+    unsigned Idx = It->second.Offset;
     switch (AK) {
     case DerefKind::Read:
       return DiscardResult ? true : this->emitGetParam(T, Idx, LV);
@@ -2153,18 +2153,19 @@ bool ByteCodeExprGen<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) {
     return this->emitGetPtrGlobal(*GlobalIndex, E);
   } else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
     if (auto It = this->Params.find(PVD); It != this->Params.end()) {
-      if (IsReference)
-        return this->emitGetParamPtr(It->second, E);
-      return this->emitGetPtrParam(It->second, E);
+      if (IsReference || !It->second.IsPtr)
+        return this->emitGetParamPtr(It->second.Offset, E);
+
+      return this->emitGetPtrParam(It->second.Offset, E);
     }
   }
 
   // Handle lambda captures.
   if (auto It = this->LambdaCaptures.find(D);
       It != this->LambdaCaptures.end()) {
-    auto [Offset, IsReference] = It->second;
+    auto [Offset, IsPtr] = It->second;
 
-    if (IsReference)
+    if (IsPtr)
       return this->emitGetThisFieldPtr(Offset, E);
     return this->emitGetPtrThisField(Offset, E);
   }

diff  --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index e54805cd931aef..f048b2c218a4ca 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -125,7 +125,7 @@ bool ByteCodeStmtGen<Emitter>::emitLambdaStaticInvokerBody(
     // We do the lvalue-to-rvalue conversion manually here, so no need
     // to care about references.
     PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr);
-    if (!this->emitGetParam(ParamType, It->second, MD))
+    if (!this->emitGetParam(ParamType, It->second.Offset, MD))
       return false;
   }
 

diff  --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h
index 19d480d912116b..f5dc80af757a14 100644
--- a/clang/lib/AST/Interp/Context.h
+++ b/clang/lib/AST/Interp/Context.h
@@ -31,6 +31,11 @@ class Program;
 class State;
 enum PrimType : unsigned;
 
+struct ParamOffset {
+  unsigned Offset;
+  bool IsPtr;
+};
+
 /// Holds all information required to evaluate constexpr code in a module.
 class Context final {
 public:

diff  --git a/clang/lib/AST/Interp/EvalEmitter.h b/clang/lib/AST/Interp/EvalEmitter.h
index d1901359f2c2ed..1f392a13b3ccf7 100644
--- a/clang/lib/AST/Interp/EvalEmitter.h
+++ b/clang/lib/AST/Interp/EvalEmitter.h
@@ -75,10 +75,9 @@ class EvalEmitter : public SourceMapper {
   }
 
   /// Parameter indices.
-  llvm::DenseMap<const ParmVarDecl *, unsigned> Params;
+  llvm::DenseMap<const ParmVarDecl *, ParamOffset> Params;
   /// Lambda captures.
-  /// Map from Decl* to [Offset, IsReference] pair.
-  llvm::DenseMap<const ValueDecl *, std::pair<unsigned, bool>> LambdaCaptures;
+  llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures;
   unsigned LambdaThisCapture;
   /// Local descriptors.
   llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;


        


More information about the cfe-commits mailing list