Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -3202,6 +3202,9 @@ "cast to %1 from smaller integer type %0">, InGroup; +def warn_attribute_ignored_for_field_of_type : Warning< + "%0 attribute ignored for field of type %1">, + InGroup; def warn_no_underlying_type_specified_for_enum_bitfield : Warning< "enums in the Microsoft ABI are signed integers by default; consider giving " "the enum %0 an unsigned underlying type to make this code portable">, Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -1304,14 +1304,28 @@ TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); else if (FieldDecl *FD = dyn_cast(D)) { - // Report warning about changed offset in the newer compiler versions. - if (!FD->getType()->isDependentType() && - !FD->getType()->isIncompleteType() && FD->isBitField() && - S.Context.getTypeAlign(FD->getType()) <= 8) - S.Diag(Attr.getLoc(), diag::warn_attribute_packed_for_bitfield); + bool BitfieldByteAligned = (!FD->getType()->isDependentType() && + !FD->getType()->isIncompleteType() && + FD->isBitField() && + S.Context.getTypeAlign(FD->getType()) <= 8); + + if (S.getASTContext().getTargetInfo().getTriple().isPS4()) { + if (BitfieldByteAligned) + // The PS4 target needs to maintain ABI backwards compatibility. + S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) + << Attr.getName() << FD->getType(); + else + FD->addAttr(::new (S.Context) PackedAttr( + Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); + } else { + // Report warning about changed offset in the newer compiler versions. + if (BitfieldByteAligned) + S.Diag(Attr.getLoc(), diag::warn_attribute_packed_for_bitfield); + + FD->addAttr(::new (S.Context) PackedAttr( + Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); + } - FD->addAttr(::new (S.Context) PackedAttr( - Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); } else S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); } Index: test/Sema/struct-packed-align.c =================================================================== --- test/Sema/struct-packed-align.c +++ test/Sema/struct-packed-align.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify // RUN: %clang_cc1 %s -fsyntax-only -triple=x86_64-windows-coff -verify +// RUN: %clang_cc1 %s -fsyntax-only -triple=x86_64-scei-ps4 -verify // Packed structs. struct s { @@ -146,13 +147,24 @@ // See the documentation of -Wpacked-bitfield-compat for more information. struct packed_chars { char a:4; +#ifdef __ORBIS__ + // Test for pre-r254596 clang behavior on the PS4 target. PS4 must maintain + // ABI backwards compatibility. + char b:8 __attribute__ ((packed)); + // expected-warning@-1 {{'packed' attribute ignored for field of type 'char'}} + char c:4; +#else char b:8 __attribute__ ((packed)); // expected-warning@-1 {{'packed' attribute was ignored on bit-fields with single-byte alignment in older versions of GCC and Clang}} char c:4; +#endif }; -#if defined(_WIN32) && !defined(__declspec) // _MSC_VER is unavailable in cc1. +#if (defined(_WIN32) || defined(__ORBIS__)) && !defined(__declspec) // _MSC_VER is unavailable in cc1. // On Windows clang uses MSVC compatible layout in this case. +// +// Additionally, test for pre-r254596 clang behavior on the PS4 target. PS4 +// must maintain ABI backwards compatibility. extern int o1[sizeof(struct packed_chars) == 3 ? 1 : -1]; extern int o2[__alignof(struct packed_chars) == 1 ? 1 : -1]; #else