https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/111110
Make isArrayElement() return true here, so we can know that such a pointer is in fact an array element and handle it properly in toAPValue(). >From d9ca4e19a4f5f9f17f941661782f20055ba1c6fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Fri, 4 Oct 2024 08:37:16 +0200 Subject: [PATCH] [clang][bytecode] Change isArrayElement() for narrowed composite arrays Make isArrayElement() return true here, so we can know that such a pointer is in fact an array element and handle it properly in toAPValue(). --- clang/lib/AST/ByteCode/Descriptor.cpp | 3 +++ clang/lib/AST/ByteCode/Descriptor.h | 4 +++- clang/lib/AST/ByteCode/Pointer.cpp | 8 ++++++-- clang/lib/AST/ByteCode/Pointer.h | 14 ++++++++++++-- clang/test/CodeGen/2008-08-07-AlignPadding1.c | 1 + clang/unittests/AST/ByteCode/Descriptor.cpp | 8 ++++---- 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp index 65ac7a3129abaf..5a8a2b64d5582d 100644 --- a/clang/lib/AST/ByteCode/Descriptor.cpp +++ b/clang/lib/AST/ByteCode/Descriptor.cpp @@ -103,6 +103,7 @@ static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst, Desc->IsConst = IsConst || D->IsConst; Desc->IsFieldMutable = IsMutable || D->IsMutable; Desc->InUnion = InUnion; + Desc->IsArrayElement = true; if (auto Fn = D->ElemDesc->CtorFn) Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsActive, @@ -408,6 +409,8 @@ QualType Descriptor::getType() const { QualType Descriptor::getElemQualType() const { assert(isArray()); QualType T = getType(); + if (T->isPointerOrReferenceType()) + return T->getPointeeType(); if (const auto *AT = T->getAsArrayTypeUnsafe()) return AT->getElementType(); if (const auto *CT = T->getAs<ComplexType>()) diff --git a/clang/lib/AST/ByteCode/Descriptor.h b/clang/lib/AST/ByteCode/Descriptor.h index 5460199e0e991a..85e5c37ad2f896 100644 --- a/clang/lib/AST/ByteCode/Descriptor.h +++ b/clang/lib/AST/ByteCode/Descriptor.h @@ -96,12 +96,14 @@ struct InlineDescriptor { /// Flag indicating if the field is mutable (if in a record). LLVM_PREFERRED_TYPE(bool) unsigned IsFieldMutable : 1; + unsigned IsArrayElement : 1; const Descriptor *Desc; InlineDescriptor(const Descriptor *D) : Offset(sizeof(InlineDescriptor)), IsConst(false), IsInitialized(false), - IsBase(false), IsActive(false), IsFieldMutable(false), Desc(D) {} + IsBase(false), IsActive(false), IsFieldMutable(false), + IsArrayElement(false), Desc(D) {} void dump() const { dump(llvm::errs()); } void dump(llvm::raw_ostream &OS) const; diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp index 387cad9b137c02..a52f0e336ef298 100644 --- a/clang/lib/AST/ByteCode/Pointer.cpp +++ b/clang/lib/AST/ByteCode/Pointer.cpp @@ -204,18 +204,22 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const { Path.push_back(APValue::LValuePathEntry( {Ptr.getFieldDesc()->asDecl(), /*IsVirtual=*/false})); - if (const auto *FD = dyn_cast<FieldDecl>(Ptr.getFieldDesc()->asDecl())) + if (const auto *FD = + dyn_cast_if_present<FieldDecl>(Ptr.getFieldDesc()->asDecl())) Offset += getFieldOffset(FD); Ptr = Ptr.getBase(); } else if (Ptr.isArrayElement()) { + Ptr = Ptr.expand(); unsigned Index; if (Ptr.isOnePastEnd()) Index = Ptr.getArray().getNumElems(); else Index = Ptr.getIndex(); - Offset += (Index * ASTCtx.getTypeSizeInChars(Ptr.getType())); + QualType ElemType = Ptr.getFieldDesc()->getElemQualType(); + Offset += (Index * ASTCtx.getTypeSizeInChars(ElemType)); + Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index)); Ptr = Ptr.getArray(); } else { diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h index ac9b9ed4091b66..08bc4b7e40b636 100644 --- a/clang/lib/AST/ByteCode/Pointer.h +++ b/clang/lib/AST/ByteCode/Pointer.h @@ -420,8 +420,18 @@ class Pointer { } /// Checks if the pointer points to an array. bool isArrayElement() const { - if (isBlockPointer()) - return inArray() && asBlockPointer().Base != Offset; + if (!isBlockPointer()) + return false; + + const BlockPointer &BP = asBlockPointer(); + if (inArray() && BP.Base != Offset) + return true; + + // Might be a narrow()'ed element in a composite array. + // Check the inline descriptor. + if (BP.Base >= sizeof(InlineDescriptor) && getInlineDesc()->IsArrayElement) + return true; + return false; } /// Pointer points directly to a block. diff --git a/clang/test/CodeGen/2008-08-07-AlignPadding1.c b/clang/test/CodeGen/2008-08-07-AlignPadding1.c index 17e88ce02659f0..b51bcbc0244da8 100644 --- a/clang/test/CodeGen/2008-08-07-AlignPadding1.c +++ b/clang/test/CodeGen/2008-08-07-AlignPadding1.c @@ -1,4 +1,5 @@ /* RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-darwin -o - | FileCheck %s +/* RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-darwin -o - -fexperimental-new-constant-interpreter | FileCheck %s The FE must generate padding here both at the end of each PyG_Head and between array elements. Reduced from Python. */ diff --git a/clang/unittests/AST/ByteCode/Descriptor.cpp b/clang/unittests/AST/ByteCode/Descriptor.cpp index 9e09c7f15ac9a2..b3517d8731c85b 100644 --- a/clang/unittests/AST/ByteCode/Descriptor.cpp +++ b/clang/unittests/AST/ByteCode/Descriptor.cpp @@ -251,7 +251,7 @@ TEST(Descriptor, Primitives) { ASSERT_TRUE(NE1.isLive()); ASSERT_EQ(NE1.getIndex(), 0); ASSERT_TRUE(NE1.isInitialized()); - ASSERT_FALSE(NE1.isArrayElement()); + ASSERT_TRUE(NE1.isArrayElement()); ASSERT_TRUE(NE1.isField()); ASSERT_FALSE(NE1.inArray()); ASSERT_FALSE(NE1.isArrayRoot()); @@ -279,7 +279,7 @@ TEST(Descriptor, Primitives) { ASSERT_TRUE(NE2.isLive()); ASSERT_EQ(NE2.getIndex(), 0); ASSERT_TRUE(NE2.isInitialized()); - ASSERT_FALSE(NE2.isArrayElement()); + ASSERT_TRUE(NE2.isArrayElement()); ASSERT_TRUE(NE2.isField()); ASSERT_FALSE(NE2.inArray()); ASSERT_FALSE(NE2.isArrayRoot()); @@ -344,7 +344,7 @@ TEST(Descriptor, Primitives) { ASSERT_NE(NE1, PF4); ASSERT_NE(NE1, E1); ASSERT_TRUE(NE1.isLive()); - ASSERT_FALSE(NE1.isArrayElement()); + ASSERT_TRUE(NE1.isArrayElement()); ASSERT_TRUE(NE1.isArrayRoot()); ASSERT_FALSE(NE1.getFieldDesc()->isCompositeArray()); ASSERT_TRUE(NE1.getFieldDesc()->isPrimitiveArray()); @@ -375,7 +375,7 @@ TEST(Descriptor, Primitives) { ASSERT_NE(NE3, PF4); ASSERT_NE(NE3, E1); ASSERT_TRUE(NE3.isLive()); - ASSERT_FALSE(NE3.isArrayElement()); + ASSERT_TRUE(NE3.isArrayElement()); ASSERT_TRUE(NE3.isArrayRoot()); ASSERT_FALSE(NE3.getFieldDesc()->isCompositeArray()); ASSERT_TRUE(NE3.getFieldDesc()->isPrimitiveArray()); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits