]> granicus.if.org Git - clang/commitdiff
IRgen: Always use i8 arrays to access union bit-fields. This is ugly, but
authorDaniel Dunbar <daniel@zuster.org>
Tue, 20 Apr 2010 17:52:30 +0000 (17:52 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 20 Apr 2010 17:52:30 +0000 (17:52 +0000)
matches how we currently handle structs, and this correctly handles
-fno-bitfield-type-align.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101918 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGRecordLayoutBuilder.cpp
test/CodeGen/bitfield-2.c

index 7b7394a81968b4bf63df10b7c5185671437fb335..89b62bfa5a84188f999ca4e967c7af4ebedbd21b 100644 (file)
@@ -323,28 +323,19 @@ CGRecordLayoutBuilder::LayoutUnionField(const FieldDecl *Field,
     if (FieldSize == 0)
       return 0;
 
-    const llvm::Type *FieldTy;
-
-    if (!Field->getDeclName()) {
-      // This is an unnamed bit-field, which shouldn't affect alignment on the
-      // struct so we use an array of bytes for it.
-
-      FieldTy = llvm::Type::getInt8Ty(Types.getLLVMContext());
+    const llvm::Type *FieldTy = llvm::Type::getInt8Ty(Types.getLLVMContext());
+    unsigned NumBytesToAppend =
+      llvm::RoundUpToAlignment(FieldSize, 8) / 8;
 
-      unsigned NumBytesToAppend =
-        llvm::RoundUpToAlignment(FieldSize, 8) / 8;
+    if (NumBytesToAppend > 1)
+      FieldTy = llvm::ArrayType::get(FieldTy, NumBytesToAppend);
 
-      if (NumBytesToAppend > 1)
-        FieldTy = llvm::ArrayType::get(FieldTy, NumBytesToAppend);
-    } else 
-      FieldTy = Types.ConvertTypeForMemRecursive(Field->getType());
-    
     // Add the bit field info.
     LLVMBitFields.push_back(
       LLVMBitFieldInfo(Field, ComputeBitFieldInfo(Types, Field, 0, FieldSize)));
     return FieldTy;
   }
-  
+
   // This is a regular union field.
   LLVMFields.push_back(LLVMFieldInfo(Field, 0));
   return Types.ConvertTypeForMemRecursive(Field->getType());
index 94f275d7d5b9a991a836a483a95c476b334dedf4..872312f622e5f48dfc99ce471e91093b6283799c 100644 (file)
@@ -175,7 +175,6 @@ unsigned long long test_4() {
 
 /***/
 
-
 struct s5 {
   unsigned f0 : 2;
   _Bool f1 : 1;
@@ -206,18 +205,32 @@ unsigned long long test_5() {
   return res;
 }
 
-struct A {
-  _Bool b : 2;
+/***/
+
+struct s6 {
+  _Bool f0 : 2;
 };
 
+struct s6 g6 = { 0xF };
+
+int f6_load(struct s6 *a0) {
+  return a0->f0;
+}
+int f6_store(struct s6 *a0) {
+  return a0->f0 = 0x0;
+}
+int f6_reload(struct s6 *a0) {
+  return (a0->f0 += 0xF);
+}
+
 // CHECK-OPT: define zeroext i1 @test_6()
-// CHECK-OPT: ret i1 true
+// CHECK-OPT:  ret i1 true
 // CHECK-OPT: }
 _Bool test_6() {
-  struct A a;
-  
-  a.b = (_Bool)0;
-  
-  return (a.b = !a.b);
+  struct s6 g6 = { 0xF };
+  unsigned long long res = 0;
+  res ^= g6.f0;
+  res ^= f6_load(&g6);
+  res ^= g6.f0;
+  return res;
 }
-