aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Ramos Venancio <lauro.venancio@gmail.com>2008-02-07 18:18:58 +0000
committerLauro Ramos Venancio <lauro.venancio@gmail.com>2008-02-07 18:18:58 +0000
commit8432f4b4cdd1707f7f5dc06f35b4597dca252f2c (patch)
treee9394b4697922ea6e1d116c8a2c8256fa303d76d
parent61900f0ef4fc705e62609939f30a375a9576e43d (diff)
Fix codegen of
struct { char a[3]; unsigned char b:1; }; Fix PR1990. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46856 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--CodeGen/CodeGenTypes.cpp13
-rw-r--r--test/CodeGen/2008-02-07-bitfield-bug.c11
2 files changed, 20 insertions, 4 deletions
diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp
index 3f5449056a..93b441bc62 100644
--- a/CodeGen/CodeGenTypes.cpp
+++ b/CodeGen/CodeGenTypes.cpp
@@ -477,6 +477,7 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
/// addPaddingFields - Current cursor is not suitable place to add next field.
/// Add required padding fields.
void RecordOrganizer::addPaddingFields(unsigned WaterMark) {
+ assert(WaterMark >= llvmSize && "Invalid padding Field");
unsigned RequiredBits = WaterMark - llvmSize;
unsigned RequiredBytes = (RequiredBits + 7) / 8;
for (unsigned i = 0; i != RequiredBytes; ++i)
@@ -573,7 +574,7 @@ void RecordOrganizer::placeBitField(const FieldDecl *FD) {
uint64_t O = Offsets[i - 1];
if (O % TySize == 0) {
FoundPrevField = true;
- if (TySize - (Cursor - O) >= BitFieldSize) {
+ if (TySize > (Cursor - O) && TySize - (Cursor - O) >= BitFieldSize) {
// The bitfield fits in the last aligned field.
// This is : struct { char a; int CurrentField:10;};
// where 'CurrentField' shares first field with 'a'.
@@ -585,11 +586,15 @@ void RecordOrganizer::placeBitField(const FieldDecl *FD) {
// Place the bitfield in a new LLVM field.
// This is : struct { char a; short CurrentField:10;};
// where 'CurrentField' needs a new llvm field.
- addPaddingFields(O + TySize);
+ unsigned Padding = 0;
+ if (Cursor % TySize) {
+ Padding = TySize - (Cursor % TySize);
+ addPaddingFields(Cursor + Padding);
+ }
CGT.addFieldInfo(FD, llvmFieldNo);
CGT.addBitFieldInfo(FD, 0, BitFieldSize);
- addPaddingFields(O + TySize + BitFieldSize);
- Cursor = O + TySize + BitFieldSize;
+ Cursor += Padding + BitFieldSize;
+ addPaddingFields(Cursor);
}
break;
}
diff --git a/test/CodeGen/2008-02-07-bitfield-bug.c b/test/CodeGen/2008-02-07-bitfield-bug.c
new file mode 100644
index 0000000000..996cc4c56a
--- /dev/null
+++ b/test/CodeGen/2008-02-07-bitfield-bug.c
@@ -0,0 +1,11 @@
+// RUN: clang %s -emit-llvm
+// PR1990
+
+struct test {
+ char a[3];
+ unsigned char b:1;
+};
+
+void f(struct test *t) {
+ t->b = 1;
+}