Index: lib/AST/RecordLayoutBuilder.cpp =================================================================== --- lib/AST/RecordLayoutBuilder.cpp +++ lib/AST/RecordLayoutBuilder.cpp @@ -1710,10 +1710,17 @@ FieldAlign = std::max(FieldAlign, MaxAlignmentInChars); UnpackedFieldAlign = std::max(UnpackedFieldAlign, MaxAlignmentInChars); - // The maximum field alignment overrides the aligned attribute. + // The maximum field alignment overrides the aligned attribute iff we are not + // in ms_abi mode, MSVC obeys __declspec(alignment) requests despite pragma + // pack. if (!MaxFieldAlignment.isZero()) { FieldAlign = std::min(FieldAlign, MaxFieldAlignment); UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignment); + if (IsMsStruct) { + // Respect align attributes. + FieldAlign = std::max(FieldAlign, MaxAlignmentInChars); + UnpackedFieldAlign = std::max(UnpackedFieldAlign, MaxAlignmentInChars); + } } // Round up the current record size to the field's alignment boundary. Index: test/Sema/pragma-ms_struct.c =================================================================== --- test/Sema/pragma-ms_struct.c +++ test/Sema/pragma-ms_struct.c @@ -61,3 +61,10 @@ struct __declspec(ms_struct) bad { // expected-warning {{__declspec attribute 'ms_struct' is not supported}} }; + +#pragma ms_struct on +#pragma pack(push, 1) +struct S1 { char a; short b; double c; __attribute__((aligned(32))) double d; char e; double f; }; +#pragma pack(pop) +static int arr2[sizeof(struct S1) == 64 ? 1 : -1]; +#pragma ms_struct off