summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2010-06-29 18:34:35 +0000
committerDaniel Dunbar <daniel@zuster.org>2010-06-29 18:34:35 +0000
commitf35e76552f68dc07bedc75f006e0ae1a9a18e81c (patch)
treeb8d67f07bd9c0202731adf2b7e05cd6d7dd306fc
parenta4575f5b31fdf23633dfe5cc71d9da24a074aa3d (diff)
downloadbcm5719-llvm-f35e76552f68dc07bedc75f006e0ae1a9a18e81c.tar.gz
bcm5719-llvm-f35e76552f68dc07bedc75f006e0ae1a9a18e81c.zip
Sema: Fix a subtle i64 -> i32 truncation which broke layout of large structures
with bit-fields. llvm-svn: 107185
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp2
-rw-r--r--clang/test/Sema/bitfield-layout.c10
2 files changed, 11 insertions, 1 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 275daf6bb22..88d71ce0428 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -1296,7 +1296,7 @@ void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
// Check if we need to add padding to give the field the correct alignment.
if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
- FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
+ FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
// Padding members don't affect overall alignment.
if (!D->getIdentifier())
diff --git a/clang/test/Sema/bitfield-layout.c b/clang/test/Sema/bitfield-layout.c
index edc44bdefa0..2655fc70cd4 100644
--- a/clang/test/Sema/bitfield-layout.c
+++ b/clang/test/Sema/bitfield-layout.c
@@ -30,3 +30,13 @@ CHECK_ALIGN(struct, e, 1)
struct f {__attribute((aligned(8))) int x : 30, y : 30, z : 30;};
CHECK_SIZE(struct, f, 24)
CHECK_ALIGN(struct, f, 8)
+
+// Large structure (overflows i32, in bits).
+struct s0 {
+ char a[0x32100000];
+ int x:30, y:30;
+};
+
+CHECK_SIZE(struct, s0, 0x32100008)
+CHECK_ALIGN(struct, s0, 4)
+
OpenPOWER on IntegriCloud