[PATCH] D79052: [clang codegen] Fix alignment of "Address" for incomplete array pointer.

Eli Friedman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 2 14:50:34 PDT 2020


efriedma updated this revision to Diff 267994.
efriedma added a comment.

"Address" the review comments.  Not really happy with this, but not sure what else to do.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79052/new/

https://reviews.llvm.org/D79052

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/alignment.cpp


Index: clang/test/CodeGenCXX/alignment.cpp
===================================================================
--- clang/test/CodeGenCXX/alignment.cpp
+++ clang/test/CodeGenCXX/alignment.cpp
@@ -309,3 +309,7 @@
     AlignedArray result = d.bArray;
   }
 }
+
+// CHECK-LABEL: @_Z22incomplete_array_derefPA_i
+// CHECK: load i32, i32* {{%.*}}, align 4
+int incomplete_array_deref(int (*p)[]) { return (*p)[2]; }
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -5993,32 +5993,58 @@
     }
   }
 
+  bool AlignForArray = T->isArrayType();
+
+  // Analyze the base element type, so we don't get confused by incomplete
+  // array types.
+  T = getBaseElementType(T);
+
+  if (T->isIncompleteType()) {
+    // FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown. But we
+    // that doesn't return whether we got the alignment from an attribute.
+    if (const auto *TT = T->getAs<TypedefType>()) {
+      if (unsigned Align = TT->getDecl()->getMaxAlignment()) {
+        if (BaseInfo)
+          *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType);
+        return getContext().toCharUnitsFromBits(Align);
+      }
+    }
+
+    // Otherwise, see if the declaration of the type had an attribute.
+    if (const auto *TT = T->getAs<TagType>()) {
+      if (BaseInfo)
+        *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType);
+      return getContext().toCharUnitsFromBits(TT->getDecl()->getMaxAlignment());
+    }
+
+    // The alignment is completely unknown; just return one.
+    if (BaseInfo)
+      *BaseInfo = LValueBaseInfo(AlignmentSource::Type);
+    return CharUnits::One();
+  }
+
   if (BaseInfo)
     *BaseInfo = LValueBaseInfo(AlignmentSource::Type);
 
   CharUnits Alignment;
-  if (T->isIncompleteType()) {
-    Alignment = CharUnits::One(); // Shouldn't be used, but pessimistic is best.
+  // For C++ class pointees, we don't know whether we're pointing at a
+  // base or a complete object, so we generally need to use the
+  // non-virtual alignment.
+  const CXXRecordDecl *RD;
+  if (forPointeeType && !AlignForArray && (RD = T->getAsCXXRecordDecl())) {
+    Alignment = getClassPointerAlignment(RD);
   } else {
-    // For C++ class pointees, we don't know whether we're pointing at a
-    // base or a complete object, so we generally need to use the
-    // non-virtual alignment.
-    const CXXRecordDecl *RD;
-    if (forPointeeType && (RD = T->getAsCXXRecordDecl())) {
-      Alignment = getClassPointerAlignment(RD);
-    } else {
-      Alignment = getContext().getTypeAlignInChars(T);
-      if (T.getQualifiers().hasUnaligned())
-        Alignment = CharUnits::One();
-    }
+    Alignment = getContext().getTypeAlignInChars(T);
+    if (T.getQualifiers().hasUnaligned())
+      Alignment = CharUnits::One();
+  }
 
-    // Cap to the global maximum type alignment unless the alignment
-    // was somehow explicit on the type.
-    if (unsigned MaxAlign = getLangOpts().MaxTypeAlign) {
-      if (Alignment.getQuantity() > MaxAlign &&
-          !getContext().isAlignmentRequired(T))
-        Alignment = CharUnits::fromQuantity(MaxAlign);
-    }
+  // Cap to the global maximum type alignment unless the alignment
+  // was somehow explicit on the type.
+  if (unsigned MaxAlign = getLangOpts().MaxTypeAlign) {
+    if (Alignment.getQuantity() > MaxAlign &&
+        !getContext().isAlignmentRequired(T))
+      Alignment = CharUnits::fromQuantity(MaxAlign);
   }
   return Alignment;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79052.267994.patch
Type: text/x-patch
Size: 3595 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200602/b1d74dd8/attachment-0001.bin>


More information about the cfe-commits mailing list