[clang] 800b073 - [clang][bytecode] Change isArrayElement() for narrowed composite arrays (#111110)

via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 4 05:19:35 PDT 2024


Author: Timm Baeder
Date: 2024-10-04T14:19:32+02:00
New Revision: 800b07396ff54b037fa9b73bb15586456656fb79

URL: https://github.com/llvm/llvm-project/commit/800b07396ff54b037fa9b73bb15586456656fb79
DIFF: https://github.com/llvm/llvm-project/commit/800b07396ff54b037fa9b73bb15586456656fb79.diff

LOG: [clang][bytecode] Change isArrayElement() for narrowed composite arrays (#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().

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Descriptor.cpp
    clang/lib/AST/ByteCode/Descriptor.h
    clang/lib/AST/ByteCode/Pointer.cpp
    clang/lib/AST/ByteCode/Pointer.h
    clang/test/CodeGen/2008-08-07-AlignPadding1.c
    clang/unittests/AST/ByteCode/Descriptor.cpp

Removed: 
    


################################################################################
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..bcb635e157f009 100644
--- a/clang/lib/AST/ByteCode/Descriptor.h
+++ b/clang/lib/AST/ByteCode/Descriptor.h
@@ -96,12 +96,16 @@ struct InlineDescriptor {
   /// Flag indicating if the field is mutable (if in a record).
   LLVM_PREFERRED_TYPE(bool)
   unsigned IsFieldMutable : 1;
+  /// Flag indicating if the field is an element of a composite array.
+  LLVM_PREFERRED_TYPE(bool)
+  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());


        


More information about the cfe-commits mailing list