diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 88e1d04ddf89..2ed345aec8d4 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1387,7 +1387,9 @@ static getConstantArrayInfoInChars(const ASTContext &Context, "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 *T) const { "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: diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index fb35343a477c..87d00bc9f5d1 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2140,23 +2140,8 @@ public: std::pair MicrosoftRecordLayoutBuilder::getAdjustedFieldInfo(const FieldDecl *FD) { - std::pair 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()) { - 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 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::getAdjustedFieldInfo(const FieldDecl *FD) { 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(); diff --git a/clang/test/Layout/ms-x86-misalignedarray.cpp b/clang/test/Layout/ms-x86-misalignedarray.cpp new file mode 100644 index 000000000000..f6887daf15b6 --- /dev/null +++ b/clang/test/Layout/ms-x86-misalignedarray.cpp @@ -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)];