Author: Timm Bäder Date: 2024-07-23T16:06:04+02:00 New Revision: 5589f2977117ec4685018472ca5f01355424bab9
URL: https://github.com/llvm/llvm-project/commit/5589f2977117ec4685018472ca5f01355424bab9 DIFF: https://github.com/llvm/llvm-project/commit/5589f2977117ec4685018472ca5f01355424bab9.diff LOG: [clang][Interp] Merge FunctionPointer into Pointer Back when I introduced the FunctionPointer class, I assumed that we can always know that a Pointer is not a FunctionPointer. With the DecayPtr op, that changed somewhat, but the information whether a Pointer was created through a FunctionPointer was lost. However, we need this information, especially when we're in the codegen stage. Added: Modified: clang/lib/AST/Interp/FunctionPointer.h clang/lib/AST/Interp/Interp.cpp clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Pointer.cpp clang/lib/AST/Interp/Pointer.h Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/FunctionPointer.h b/clang/lib/AST/Interp/FunctionPointer.h index 0f2c6e571a1d8..d92cd32933fcd 100644 --- a/clang/lib/AST/Interp/FunctionPointer.h +++ b/clang/lib/AST/Interp/FunctionPointer.h @@ -23,11 +23,10 @@ class FunctionPointer final { bool Valid; public: - FunctionPointer(const Function *Func) : Func(Func), Valid(true) { - assert(Func); - } + FunctionPointer() = default; + FunctionPointer(const Function *Func) : Func(Func), Valid(true) {} - FunctionPointer(uintptr_t IntVal = 0, const Descriptor *Desc = nullptr) + FunctionPointer(uintptr_t IntVal, const Descriptor *Desc = nullptr) : Func(reinterpret_cast<const Function *>(IntVal)), Valid(false) {} const Function *getFunction() const { return Func; } diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 6fcd90e5f5849..bf29b85041d82 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -333,7 +333,7 @@ bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) { } static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { - if (Ptr.isIntegralPointer()) + if (!Ptr.isBlockPointer()) return true; return CheckConstant(S, OpPC, Ptr.getDeclDesc()); } diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 8e96f78d90568..492802897f013 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -2811,6 +2811,13 @@ inline bool DecayPtr(InterpState &S, CodePtr OpPC) { using ToT = typename PrimConv<TOut>::T; const FromT &OldPtr = S.Stk.pop<FromT>(); + + if constexpr (std::is_same_v<FromT, FunctionPointer> && + std::is_same_v<ToT, Pointer>) { + S.Stk.push<Pointer>(OldPtr.getFunction()); + return true; + } + S.Stk.push<ToT>(ToT(OldPtr.getIntegerRepresentation(), nullptr)); return true; } diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index 29579f5db40b6..3ac8bc2b09709 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -55,7 +55,7 @@ Pointer::Pointer(Pointer &&P) } Pointer::~Pointer() { - if (isIntegralPointer()) + if (!isBlockPointer()) return; if (Block *Pointee = PointeeStorage.BS.Pointee) { @@ -87,6 +87,8 @@ void Pointer::operator=(const Pointer &P) { PointeeStorage.BS.Pointee->addPointer(this); } else if (P.isIntegralPointer()) { PointeeStorage.Int = P.PointeeStorage.Int; + } else if (P.isFunctionPointer()) { + PointeeStorage.Fn = P.PointeeStorage.Fn; } else { assert(false && "Unhandled storage kind"); } @@ -115,6 +117,8 @@ void Pointer::operator=(Pointer &&P) { PointeeStorage.BS.Pointee->addPointer(this); } else if (P.isIntegralPointer()) { PointeeStorage.Int = P.PointeeStorage.Int; + } else if (P.isFunctionPointer()) { + PointeeStorage.Fn = P.PointeeStorage.Fn; } else { assert(false && "Unhandled storage kind"); } @@ -131,6 +135,8 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const { CharUnits::fromQuantity(asIntPointer().Value + this->Offset), Path, /*IsOnePastEnd=*/false, /*IsNullPtr=*/false); + if (isFunctionPointer()) + return asFunctionPointer().toAPValue(ASTCtx); // Build the lvalue base from the block. const Descriptor *Desc = getDeclDesc(); @@ -263,7 +269,7 @@ std::string Pointer::toDiagnosticString(const ASTContext &Ctx) const { } bool Pointer::isInitialized() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return true; if (isRoot() && PointeeStorage.BS.Base == sizeof(GlobalInlineDescriptor)) { @@ -299,7 +305,7 @@ bool Pointer::isInitialized() const { } void Pointer::initialize() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return; assert(PointeeStorage.BS.Pointee && "Cannot initialize null pointer"); @@ -368,10 +374,15 @@ bool Pointer::hasSameBase(const Pointer &A, const Pointer &B) { if (A.isIntegralPointer() && B.isIntegralPointer()) return true; + if (A.isFunctionPointer() && B.isFunctionPointer()) + return true; if (A.isIntegralPointer() || B.isIntegralPointer()) return A.getSource() == B.getSource(); + if (A.StorageKind != B.StorageKind) + return false; + return A.asBlockPointer().Pointee == B.asBlockPointer().Pointee; } diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h index e351699023ba5..6b0c31358159c 100644 --- a/clang/lib/AST/Interp/Pointer.h +++ b/clang/lib/AST/Interp/Pointer.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_AST_INTERP_POINTER_H #include "Descriptor.h" +#include "FunctionPointer.h" #include "InterpBlock.h" #include "clang/AST/ComparisonCategories.h" #include "clang/AST/Decl.h" @@ -45,7 +46,7 @@ struct IntPointer { uint64_t Value; }; -enum class Storage { Block, Int }; +enum class Storage { Block, Int, Fn }; /// A pointer to a memory block, live or dead. /// @@ -96,6 +97,10 @@ class Pointer { PointeeStorage.Int.Value = Address; PointeeStorage.Int.Desc = Desc; } + Pointer(const Function *F, uint64_t Offset = 0) + : Offset(Offset), StorageKind(Storage::Fn) { + PointeeStorage.Fn = FunctionPointer(F); + } ~Pointer(); void operator=(const Pointer &P); @@ -126,6 +131,8 @@ class Pointer { uint64_t getIntegerRepresentation() const { if (isIntegralPointer()) return asIntPointer().Value + (Offset * elemSize()); + if (isFunctionPointer()) + return asFunctionPointer().getIntegerRepresentation(); return reinterpret_cast<uint64_t>(asBlockPointer().Pointee) + Offset; } @@ -137,6 +144,8 @@ class Pointer { [[nodiscard]] Pointer atIndex(uint64_t Idx) const { if (isIntegralPointer()) return Pointer(asIntPointer().Value, asIntPointer().Desc, Idx); + if (isFunctionPointer()) + return Pointer(asFunctionPointer().getFunction(), Idx); if (asBlockPointer().Base == RootPtrMark) return Pointer(asBlockPointer().Pointee, RootPtrMark, @@ -247,18 +256,20 @@ class Pointer { bool isZero() const { if (isBlockPointer()) return asBlockPointer().Pointee == nullptr; + if (isFunctionPointer()) + return asFunctionPointer().isZero(); assert(isIntegralPointer()); return asIntPointer().Value == 0 && Offset == 0; } /// Checks if the pointer is live. bool isLive() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return true; return asBlockPointer().Pointee && !asBlockPointer().Pointee->IsDead; } /// Checks if the item is a field in an object. bool isField() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return false; return !isRoot() && getFieldDesc()->asDecl(); @@ -268,6 +279,8 @@ class Pointer { const Descriptor *getDeclDesc() const { if (isIntegralPointer()) return asIntPointer().Desc; + if (isFunctionPointer()) + return nullptr; assert(isBlockPointer()); assert(asBlockPointer().Pointee); @@ -279,7 +292,10 @@ class Pointer { DeclTy getSource() const { if (isBlockPointer()) return getDeclDesc()->getSource(); - + if (isFunctionPointer()) { + const Function *F = asFunctionPointer().getFunction(); + return F ? F->getDecl() : DeclTy(); + } assert(isIntegralPointer()); return asIntPointer().Desc ? asIntPointer().Desc->getSource() : DeclTy(); } @@ -354,6 +370,7 @@ class Pointer { /// Returns the offset into an array. unsigned getOffset() const { assert(Offset != PastEndMark && "invalid offset"); + assert(isBlockPointer()); if (asBlockPointer().Base == RootPtrMark) return Offset; @@ -421,8 +438,14 @@ class Pointer { assert(isIntegralPointer()); return PointeeStorage.Int; } + [[nodiscard]] const FunctionPointer &asFunctionPointer() const { + assert(isFunctionPointer()); + return PointeeStorage.Fn; + } + bool isBlockPointer() const { return StorageKind == Storage::Block; } bool isIntegralPointer() const { return StorageKind == Storage::Int; } + bool isFunctionPointer() const { return StorageKind == Storage::Fn; } /// Returns the record descriptor of a class. const Record *getRecord() const { return getFieldDesc()->ElemRecord; } @@ -445,7 +468,7 @@ class Pointer { } /// Checks if the storage is static. bool isStatic() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return true; assert(asBlockPointer().Pointee); return asBlockPointer().Pointee->isStatic(); @@ -469,7 +492,7 @@ class Pointer { } bool isWeak() const { - if (isIntegralPointer()) + if (!isBlockPointer()) return false; assert(isBlockPointer()); @@ -528,8 +551,8 @@ class Pointer { /// Returns the number of elements. unsigned getNumElems() const { - if (isIntegralPointer()) - return ~unsigned(0); + if (!isBlockPointer()) + return ~0u; return getSize() / elemSize(); } @@ -555,7 +578,7 @@ class Pointer { /// Checks if the index is one past end. bool isOnePastEnd() const { - if (isIntegralPointer()) + if (isIntegralPointer() || isFunctionPointer()) return false; if (!asBlockPointer().Pointee) @@ -692,6 +715,7 @@ class Pointer { union { BlockPointer BS; IntPointer Int; + FunctionPointer Fn; } PointeeStorage; Storage StorageKind = Storage::Int; }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits