r193898 - Improves compatibility with cl.exe when laying out array fields

Warren Hunt whunt at google.com
Fri Nov 1 16:59:41 PDT 2013


Author: whunt
Date: Fri Nov  1 18:59:41 2013
New Revision: 193898

URL: http://llvm.org/viewvc/llvm-project?rev=193898&view=rev
Log:
Improves compatibility with cl.exe when laying out array fields

Differential Revision: http://llvm-reviews.chandlerc.com/D2090

Clang was "improperly" over-aligning arrays with sizes are not a multiple of 
their alignment. 
This behavior was removed in microsoft 32 bit mode.

In addition, after examination of ASTContext::getTypeInfoImpl, a redundant code block in 
MicrosoftRecordLayoutBuilder::getAdjustedFieldInfo was deleted.


Added:
    cfe/trunk/test/Layout/ms-x86-misalignedarray.cpp
Modified:
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=193898&r1=193897&r2=193898&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Nov  1 18:59:41 2013
@@ -1387,7 +1387,9 @@ static getConstantArrayInfoInChars(const
          "Overflow in array type char size evaluation");
   uint64_t Width = EltInfo.first.getQuantity() * Size;
   unsigned Align = EltInfo.second.getQuantity();
-  Width = llvm::RoundUpToAlignment(Width, Align);
+  if (!Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+      Context.getTargetInfo().getPointerWidth(0) == 64)
+    Width = llvm::RoundUpToAlignment(Width, Align);
   return std::make_pair(CharUnits::fromQuantity(Width),
                         CharUnits::fromQuantity(Align));
 }
@@ -1460,7 +1462,9 @@ ASTContext::getTypeInfoImpl(const Type *
            "Overflow in array type bit size evaluation");
     Width = EltInfo.first*Size;
     Align = EltInfo.second;
-    Width = llvm::RoundUpToAlignment(Width, Align);
+    if (!getTargetInfo().getCXXABI().isMicrosoft() ||
+        getTargetInfo().getPointerWidth(0) == 64)
+      Width = llvm::RoundUpToAlignment(Width, Align);
     break;
   }
   case Type::ExtVector:

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=193898&r1=193897&r2=193898&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Fri Nov  1 18:59:41 2013
@@ -2140,23 +2140,8 @@ public:
 
 std::pair<CharUnits, CharUnits>
 MicrosoftRecordLayoutBuilder::getAdjustedFieldInfo(const FieldDecl *FD) {
-  std::pair<CharUnits, CharUnits> FieldInfo;
-  if (FD->getType()->isIncompleteArrayType()) {
-    // This is a flexible array member; we can't directly
-    // query getTypeInfo about these, so we figure it out here.
-    // Flexible array members don't have any size, but they
-    // have to be aligned appropriately for their element type.
-    FieldInfo.first = CharUnits::Zero();
-    const ArrayType *ATy = Context.getAsArrayType(FD->getType());
-    FieldInfo.second = Context.getTypeAlignInChars(ATy->getElementType());
-  } else if (const ReferenceType *RT = FD->getType()->getAs<ReferenceType>()) {
-    unsigned AS = RT->getPointeeType().getAddressSpace();
-    FieldInfo.first = Context
-        .toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(AS));
-    FieldInfo.second = Context
-        .toCharUnitsFromBits(Context.getTargetInfo().getPointerAlign(AS));
-  } else
-    FieldInfo = Context.getTypeInfoInChars(FD->getType());
+  std::pair<CharUnits, CharUnits> FieldInfo =
+      Context.getTypeInfoInChars(FD->getType());
 
   // If we're not on win32 and using ms_struct the field alignment will be wrong
   // for 64 bit types, so we fix that here.
@@ -2187,8 +2172,7 @@ MicrosoftRecordLayoutBuilder::getAdjuste
 
 void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) {
   IsUnion = RD->isUnion();
-  Is64BitMode = RD->getASTContext().getTargetInfo().getTriple().getArch() ==
-      llvm::Triple::x86_64;
+  Is64BitMode = Context.getTargetInfo().getPointerWidth(0) == 64;
 
   Size = CharUnits::Zero();
   Alignment = CharUnits::One();

Added: cfe/trunk/test/Layout/ms-x86-misalignedarray.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/ms-x86-misalignedarray.cpp?rev=193898&view=auto
==============================================================================
--- cfe/trunk/test/Layout/ms-x86-misalignedarray.cpp (added)
+++ cfe/trunk/test/Layout/ms-x86-misalignedarray.cpp Fri Nov  1 18:59:41 2013
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \
+// RUN:            | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN:            | FileCheck %s -check-prefix CHECK-X64
+
+struct T0 { char c; };
+struct T2 : virtual T0 { };
+struct T3 { T2 a[1]; char c; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK:    0 | struct T3
+// CHECK:    0 |   struct T2 [1] a
+// CHECK:    5 |   char c
+// CHECK:      | [sizeof=8, align=4
+// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64:    0 | struct T3
+// CHECK-X64:    0 |   struct T2 [1] a
+// CHECK-X64:   16 |   char c
+// CHECK-X64:      | [sizeof=24, align=8
+// CHECK-X64:      |  nvsize=24, nvalign=8]
+
+int a[sizeof(T3)];





More information about the cfe-commits mailing list