summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2015-12-03 09:34:49 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2015-12-03 09:34:49 +0000
commit830dfccfb2c06a1749938ce8cb78a1d6a295b942 (patch)
tree42469a867232eba42ec6869484c22d3573c2a97b
parent90d9ffa7d6c050aea6912e8d162031a709a4744a (diff)
downloadbcm5719-llvm-830dfccfb2c06a1749938ce8cb78a1d6a295b942.tar.gz
bcm5719-llvm-830dfccfb2c06a1749938ce8cb78a1d6a295b942.zip
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 llvm-svn: 254596
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td7
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp15
-rw-r--r--clang/test/Sema/struct-packed-align.c23
3 files changed, 32 insertions, 13 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 50122ecb8a4..e96c2338108 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2784,9 +2784,10 @@ def warn_int_to_void_pointer_cast : Warning<
"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; "
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 93e9eb15b36..fed22c934ce 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1073,17 +1073,14 @@ static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
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();
}
diff --git a/clang/test/Sema/struct-packed-align.c b/clang/test/Sema/struct-packed-align.c
index 417c30308ca..175866fbe97 100644
--- a/clang/test/Sema/struct-packed-align.c
+++ b/clang/test/Sema/struct-packed-align.c
@@ -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 ? 1 : -1];
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
OpenPOWER on IntegriCloud