[clang] 91ebd01 - [clang][Interp] Remove dereference()

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 21 06:26:09 PST 2024


Author: Timm Bäder
Date: 2024-02-21T15:25:55+01:00
New Revision: 91ebd010aa76a711abd88f74ecca8e82e15b23cd

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

LOG: [clang][Interp] Remove dereference()

This function tried to be smart about the dereferenced value,
but it ended up hurting more than it helped. At least in the current
state, where we still try get the correct output.

I might add something similar back later.

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/lib/AST/Interp/ByteCodeExprGen.h
    clang/lib/AST/Interp/Interp.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 70e2bca2ebf16d..d11d05dd709d5e 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -81,16 +81,15 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
     if (DiscardResult)
       return this->discard(SubExpr);
 
-    return dereference(
-        SubExpr, DerefKind::Read,
-        [](PrimType) {
-          // Value loaded - nothing to do here.
-          return true;
-        },
-        [this, CE](PrimType T) {
-          // Pointer on stack - dereference it.
-          return this->emitLoadPop(T, CE);
-        });
+    if (SubExpr->getType()->isAnyComplexType())
+      return this->delegate(SubExpr);
+
+    if (!this->visit(SubExpr))
+      return false;
+
+    if (std::optional<PrimType> SubExprT = classify(SubExpr->getType()))
+      return this->emitLoadPop(*SubExprT, CE);
+    return false;
   }
 
   case CK_UncheckedDerivedToBase:
@@ -2326,134 +2325,6 @@ bool ByteCodeExprGen<Emitter>::visitZeroRecordInitializer(const Record *R,
   return true;
 }
 
-template <class Emitter>
-bool ByteCodeExprGen<Emitter>::dereference(
-    const Expr *LV, DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
-    llvm::function_ref<bool(PrimType)> Indirect) {
-  if (std::optional<PrimType> T = classify(LV->getType())) {
-    if (!LV->refersToBitField()) {
-      // Only primitive, non bit-field types can be dereferenced directly.
-      if (const auto *DE = dyn_cast<DeclRefExpr>(LV)) {
-        if (!DE->getDecl()->getType()->isReferenceType()) {
-          if (const auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl()))
-            return dereferenceParam(LV, *T, PD, AK, Direct, Indirect);
-          if (const auto *VD = dyn_cast<VarDecl>(DE->getDecl()))
-            return dereferenceVar(LV, *T, VD, AK, Direct, Indirect);
-        }
-      }
-    }
-
-    if (!visit(LV))
-      return false;
-    return Indirect(*T);
-  }
-
-  if (LV->getType()->isAnyComplexType())
-    return this->delegate(LV);
-
-  return false;
-}
-
-template <class Emitter>
-bool ByteCodeExprGen<Emitter>::dereferenceParam(
-    const Expr *LV, PrimType T, const ParmVarDecl *PD, DerefKind AK,
-    llvm::function_ref<bool(PrimType)> Direct,
-    llvm::function_ref<bool(PrimType)> Indirect) {
-  if (auto It = this->Params.find(PD); It != this->Params.end()) {
-    unsigned Idx = It->second.Offset;
-    switch (AK) {
-    case DerefKind::Read:
-      return DiscardResult ? true : this->emitGetParam(T, Idx, LV);
-
-    case DerefKind::Write:
-      if (!Direct(T))
-        return false;
-      if (!this->emitSetParam(T, Idx, LV))
-        return false;
-      return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
-
-    case DerefKind::ReadWrite:
-      if (!this->emitGetParam(T, Idx, LV))
-        return false;
-      if (!Direct(T))
-        return false;
-      if (!this->emitSetParam(T, Idx, LV))
-        return false;
-      return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
-    }
-    return true;
-  }
-
-  // If the param is a pointer, we can dereference a dummy value.
-  if (!DiscardResult && T == PT_Ptr && AK == DerefKind::Read) {
-    if (auto Idx = P.getOrCreateDummy(PD))
-      return this->emitGetPtrGlobal(*Idx, PD);
-    return false;
-  }
-
-  // Value cannot be produced - try to emit pointer and do stuff with it.
-  return visit(LV) && Indirect(T);
-}
-
-template <class Emitter>
-bool ByteCodeExprGen<Emitter>::dereferenceVar(
-    const Expr *LV, PrimType T, const VarDecl *VD, DerefKind AK,
-    llvm::function_ref<bool(PrimType)> Direct,
-    llvm::function_ref<bool(PrimType)> Indirect) {
-  auto It = Locals.find(VD);
-  if (It != Locals.end()) {
-    const auto &L = It->second;
-    switch (AK) {
-    case DerefKind::Read:
-      if (!this->emitGetLocal(T, L.Offset, LV))
-        return false;
-      return DiscardResult ? this->emitPop(T, LV) : true;
-
-    case DerefKind::Write:
-      if (!Direct(T))
-        return false;
-      if (!this->emitSetLocal(T, L.Offset, LV))
-        return false;
-      return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
-
-    case DerefKind::ReadWrite:
-      if (!this->emitGetLocal(T, L.Offset, LV))
-        return false;
-      if (!Direct(T))
-        return false;
-      if (!this->emitSetLocal(T, L.Offset, LV))
-        return false;
-      return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
-    }
-  } else if (auto Idx = P.getGlobal(VD)) {
-    switch (AK) {
-    case DerefKind::Read:
-      if (!this->emitGetGlobal(T, *Idx, LV))
-        return false;
-      return DiscardResult ? this->emitPop(T, LV) : true;
-
-    case DerefKind::Write:
-      if (!Direct(T))
-        return false;
-      if (!this->emitSetGlobal(T, *Idx, LV))
-        return false;
-      return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
-
-    case DerefKind::ReadWrite:
-      if (!this->emitGetGlobal(T, *Idx, LV))
-        return false;
-      if (!Direct(T))
-        return false;
-      if (!this->emitSetGlobal(T, *Idx, LV))
-        return false;
-      return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
-    }
-  }
-
-  // Value cannot be produced - try to emit pointer.
-  return visit(LV) && Indirect(T);
-}
-
 template <class Emitter>
 template <typename T>
 bool ByteCodeExprGen<Emitter>::emitConst(T Value, PrimType Ty, const Expr *E) {
@@ -3092,15 +2963,9 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
     // We should already have a pointer when we get here.
     return this->delegate(SubExpr);
   case UO_Deref:  // *x
-    return dereference(
-        SubExpr, DerefKind::Read,
-        [](PrimType) {
-          llvm_unreachable("Dereferencing requires a pointer");
-          return false;
-        },
-        [this, E](PrimType T) {
-          return DiscardResult ? this->emitPop(T, E) : true;
-        });
+    if (DiscardResult)
+      return this->discard(SubExpr);
+    return this->visit(SubExpr);
   case UO_Not:    // ~x
     if (!this->visit(SubExpr))
       return false;

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 4c88e33b3ece47..8f7a0c2fc3c103 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -236,29 +236,6 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
   bool visitZeroInitializer(PrimType T, QualType QT, const Expr *E);
   bool visitZeroRecordInitializer(const Record *R, const Expr *E);
 
-  enum class DerefKind {
-    /// Value is read and pushed to stack.
-    Read,
-    /// Direct method generates a value which is written. Returns pointer.
-    Write,
-    /// Direct method receives the value, pushes mutated value. Returns pointer.
-    ReadWrite,
-  };
-
-  /// Method to directly load a value. If the value can be fetched directly,
-  /// the direct handler is called. Otherwise, a pointer is left on the stack
-  /// and the indirect handler is expected to operate on that.
-  bool dereference(const Expr *LV, DerefKind AK,
-                   llvm::function_ref<bool(PrimType)> Direct,
-                   llvm::function_ref<bool(PrimType)> Indirect);
-  bool dereferenceParam(const Expr *LV, PrimType T, const ParmVarDecl *PD,
-                        DerefKind AK,
-                        llvm::function_ref<bool(PrimType)> Direct,
-                        llvm::function_ref<bool(PrimType)> Indirect);
-  bool dereferenceVar(const Expr *LV, PrimType T, const VarDecl *PD,
-                      DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
-                      llvm::function_ref<bool(PrimType)> Indirect);
-
   /// Emits an APSInt constant.
   bool emitConst(const llvm::APSInt &Value, PrimType Ty, const Expr *E);
   bool emitConst(const llvm::APSInt &Value, const Expr *E);

diff  --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 1a48b8bddced02..82bc1f240cc51c 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -362,13 +362,13 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
   if (Ptr.isInitialized())
     return true;
 
+  if (const auto *VD = Ptr.getDeclDesc()->asVarDecl();
+      VD && VD->hasGlobalStorage()) {
+    const SourceInfo &Loc = S.Current->getSource(OpPC);
+    S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;
+    S.Note(VD->getLocation(), diag::note_declared_at);
+  }
   if (!S.checkingPotentialConstantExpression()) {
-    if (const auto *VD = Ptr.getDeclDesc()->asVarDecl();
-        VD && VD->hasGlobalStorage()) {
-      const SourceInfo &Loc = S.Current->getSource(OpPC);
-      S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;
-      S.Note(VD->getLocation(), diag::note_declared_at);
-    }
     S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_uninit)
         << AK << /*uninitialized=*/true << S.Current->getRange(OpPC);
   }


        


More information about the cfe-commits mailing list