Author: abataev Date: Thu Dec 3 03:34:49 2015 New Revision: 254596 URL: http://llvm.org/viewvc/llvm-project?rev=254596&view=rev Log: PR25575: Make GCC 4.4+ comatible layout for packed bit-fileds of char type, patch by D. Polukhin
This CL is for discussion how to better fix bit-filed layout compatibility issue with GCC (see PR25575 for test case and more details). Current clang behavior is compatible with GCC 4.1-4.3 series but it was fixed in 4.4+. Ignoring packed attribute looks very odd and because it was also fixed in GCC 4.4+, it makes sense also fix it in clang. Differential Revision: http://reviews.llvm.org/D14872 Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/test/Sema/struct-packed-align.c Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=254596&r1=254595&r2=254596&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Dec 3 03:34:49 2015 @@ -2784,9 +2784,10 @@ def warn_int_to_void_pointer_cast : Warn "cast to %1 from smaller integer type %0">, InGroup<IntToVoidPointerCast>; -def warn_attribute_ignored_for_field_of_type : Warning< - "%0 attribute ignored for field of type %1">, - InGroup<IgnoredAttributes>; +def warn_attribute_packed_for_bitfield : Warning< + "'packed' attribute was ignored on bit-fields with single-byte alignment " + "in older versions of GCC and Clang">, + InGroup<DiagGroup<"attribute-packed-for-bitfield">>; def warn_transparent_union_attribute_field_size_align : Warning< "%select{alignment|size}0 of field %1 (%2 bits) does not match the " "%select{alignment|size}0 of the first field in transparent union; " Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=254596&r1=254595&r2=254596&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Dec 3 03:34:49 2015 @@ -1073,17 +1073,14 @@ static void handlePackedAttr(Sema &S, De TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { - // If the alignment is less than or equal to 8 bits, the packed attribute - // has no effect. + // Report warning about changed offset in the newer compiler versions. if (!FD->getType()->isDependentType() && - !FD->getType()->isIncompleteType() && + !FD->getType()->isIncompleteType() && FD->isBitField() && S.Context.getTypeAlign(FD->getType()) <= 8) - 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())); + S.Diag(Attr.getLoc(), diag::warn_attribute_packed_for_bitfield); + + FD->addAttr(::new (S.Context) PackedAttr( + Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); } else S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); } Modified: cfe/trunk/test/Sema/struct-packed-align.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/struct-packed-align.c?rev=254596&r1=254595&r2=254596&view=diff ============================================================================== --- cfe/trunk/test/Sema/struct-packed-align.c (original) +++ cfe/trunk/test/Sema/struct-packed-align.c Thu Dec 3 03:34:49 2015 @@ -1,5 +1,5 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify -// expected-no-diagnostics +// RUN: %clang_cc1 %s -fsyntax-only -triple=x86_64-windows-coff -verify // Packed structs. struct s { @@ -138,3 +138,24 @@ extern int n2[__alignof(struct nS) == 8 extern int n1[sizeof(struct nS) == 9 ? 1 : -1]; extern int n2[__alignof(struct nS) == 1 ? 1 : -1]; #endif + +// Packed attribute shouldn't be ignored for bit-field of char types. +// Note from GCC reference manual: The 4.1, 4.2 and 4.3 series of GCC ignore +// the packed attribute on bit-fields of type char. This has been fixed in +// GCC 4.4 but the change can lead to differences in the structure layout. +// See the documentation of -Wpacked-bitfield-compat for more information. +struct packed_chars { + char a:4; + 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; +}; + +#if defined(_WIN32) +// On Windows clang uses MSVC compatible layout in this case. +extern int o1[sizeof(struct packed_chars) == 3 ? 1 : -1]; +extern int o2[__alignof(struct packed_chars) == 1 ? 1 : -1]; +#else +extern int o1[sizeof(struct packed_chars) == 2 ? 1 : -1]; +extern int o2[__alignof(struct packed_chars) == 1 ? 1 : -1]; +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits