diff options
Diffstat (limited to 'clang/lib/AST/ByteCode/Pointer.cpp')
| -rw-r--r-- | clang/lib/AST/ByteCode/Pointer.cpp | 75 |
1 files changed, 54 insertions, 21 deletions
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp index 38856ad256a6..ef75b0ded4f1 100644 --- a/clang/lib/AST/ByteCode/Pointer.cpp +++ b/clang/lib/AST/ByteCode/Pointer.cpp @@ -442,26 +442,42 @@ bool Pointer::isInitialized() const { assert(BS.Pointee && "Cannot check if null pointer was initialized"); const Descriptor *Desc = getFieldDesc(); assert(Desc); - if (Desc->isPrimitiveArray()) { - if (isStatic() && BS.Base == 0) - return true; + if (Desc->isPrimitiveArray()) + return isElementInitialized(getIndex()); - InitMapPtr &IM = getInitMap(); + if (asBlockPointer().Base == 0) + return true; + // Field has its bit in an inline descriptor. + return getInlineDesc()->IsInitialized; +} + +bool Pointer::isElementInitialized(unsigned Index) const { + if (!isBlockPointer()) + return true; + const Descriptor *Desc = getFieldDesc(); + assert(Desc); + + if (isStatic() && BS.Base == 0) + return true; + + if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor)) { + const GlobalInlineDescriptor &GD = + *reinterpret_cast<const GlobalInlineDescriptor *>(block()->rawData()); + return GD.InitState == GlobalInitState::Initialized; + } + + if (Desc->isPrimitiveArray()) { + InitMapPtr &IM = getInitMap(); if (!IM) return false; if (IM->first) return true; - return IM->second->isElementInitialized(getIndex()); + return IM->second->isElementInitialized(Index); } - - if (asBlockPointer().Base == 0) - return true; - - // Field has its bit in an inline descriptor. - return getInlineDesc()->IsInitialized; + return isInitialized(); } void Pointer::initialize() const { @@ -524,6 +540,23 @@ void Pointer::initializeAllElements() const { } } +bool Pointer::allElementsInitialized() const { + assert(getFieldDesc()->isPrimitiveArray()); + assert(isArrayRoot()); + + if (isStatic() && BS.Base == 0) + return true; + + if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor)) { + const GlobalInlineDescriptor &GD = + *reinterpret_cast<const GlobalInlineDescriptor *>(block()->rawData()); + return GD.InitState == GlobalInitState::Initialized; + } + + InitMapPtr &IM = getInitMap(); + return IM && IM->first; +} + void Pointer::activate() const { // Field has its bit in an inline descriptor. assert(BS.Base != 0 && "Only composite fields can be activated"); @@ -594,9 +627,6 @@ bool Pointer::hasSameBase(const Pointer &A, const Pointer &B) { if (A.isTypeidPointer() && B.isTypeidPointer()) return true; - if (A.isIntegralPointer() || B.isIntegralPointer()) - return A.getSource() == B.getSource(); - if (A.StorageKind != B.StorageKind) return false; @@ -700,7 +730,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx, return true; } - if (const auto *RT = Ty->getAs<RecordType>()) { + if (const auto *RT = Ty->getAsCanonical<RecordType>()) { const auto *Record = Ptr.getRecord(); assert(Record && "Missing record descriptor"); @@ -771,13 +801,13 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx, R = APValue(APValue::UninitArray{}, NumElems, NumElems); bool Ok = true; - for (unsigned I = 0; I < NumElems; ++I) { + OptPrimType ElemT = Ctx.classify(ElemTy); + for (unsigned I = 0; I != NumElems; ++I) { APValue &Slot = R.getArrayInitializedElt(I); - const Pointer &EP = Ptr.atIndex(I); - if (OptPrimType T = Ctx.classify(ElemTy)) { - TYPE_SWITCH(*T, Slot = EP.deref<T>().toAPValue(ASTCtx)); + if (ElemT) { + TYPE_SWITCH(*ElemT, Slot = Ptr.elem<T>(I).toAPValue(ASTCtx)); } else { - Ok &= Composite(ElemTy, EP.narrow(), Slot); + Ok &= Composite(ElemTy, Ptr.atIndex(I).narrow(), Slot); } } return Ok; @@ -785,8 +815,11 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx, // Complex types. if (const auto *CT = Ty->getAs<ComplexType>()) { - QualType ElemTy = CT->getElementType(); + // Can happen via C casts. + if (!Ptr.getFieldDesc()->isPrimitiveArray()) + return false; + QualType ElemTy = CT->getElementType(); if (ElemTy->isIntegerType()) { OptPrimType ElemT = Ctx.classify(ElemTy); assert(ElemT); |
