]> granicus.if.org Git - clang/commitdiff
Fix codegen of
authorLauro Ramos Venancio <lauro.venancio@gmail.com>
Thu, 7 Feb 2008 18:18:58 +0000 (18:18 +0000)
committerLauro Ramos Venancio <lauro.venancio@gmail.com>
Thu, 7 Feb 2008 18:18:58 +0000 (18:18 +0000)
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

CodeGen/CodeGenTypes.cpp
test/CodeGen/2008-02-07-bitfield-bug.c [new file with mode: 0644]

index 3f5449056a7b423fad69a417d7d1259db38f4924..93b441bc62b07f8bcd41555376e5d1a55b3a29e3 100644 (file)
@@ -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 (file)
index 0000000..996cc4c
--- /dev/null
@@ -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;
+}