[cfe-commits] r94796 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/arm-arguments.c

Daniel Dunbar daniel at zuster.org
Thu Jan 28 19:22:29 PST 2010


Author: ddunbar
Date: Thu Jan 28 21:22:29 2010
New Revision: 94796

URL: http://llvm.org/viewvc/llvm-project?rev=94796&view=rev
Log:
ARM/APCS ABI: Fix some problems with bit-fields in structures. After rereading
the ABI spec, this turns out to simplify the code. We still have some annoying
code which mismatches the spec with regard to empty structures.

Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/test/CodeGen/arm-arguments.c

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=94796&r1=94795&r2=94796&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Jan 28 21:22:29 2010
@@ -1611,30 +1611,30 @@
        i != e; ++i, ++idx) {
     const FieldDecl *FD = *i;
 
-    // Check if this field is at offset 0.
-    uint64_t Offset = Layout.getFieldOffset(idx);
-    if (Offset != 0) {
-      // Allow padding bit-fields, but only if they are all at the end of the
-      // structure (despite the wording above, this matches gcc).
-      if (FD->isBitField() && 
-          !FD->getBitWidth()->EvaluateAsInt(Context).getZExtValue()) {
-        for (; i != e; ++i)
-          if (!i->isBitField() ||
-              i->getBitWidth()->EvaluateAsInt(Context).getZExtValue())
-            return false;
-
-        // All remaining fields are padding, allow this.
-        return true;
-      }
+    // Bit-fields are not addressable, we only need to verify they are "integer
+    // like". We still have to disallow a subsequent non-bitfield, for example:
+    //   struct { int : 0; int x }
+    // is non-integer like according to gcc.
+    if (FD->isBitField()) {
+      if (!RD->isUnion())
+        HadField = true;
 
-      return false;
+      if (!isIntegerLikeType(FD->getType(), Context, VMContext))
+        return false;
+
+      continue;
     }
 
+    // Check if this field is at offset 0.
+    if (Layout.getFieldOffset(idx) != 0)
+      return false;
+
     if (!isIntegerLikeType(FD->getType(), Context, VMContext))
       return false;
     
-    // Only allow at most one field in a structure. Again this doesn't match the
-    // wording above, but follows gcc.
+    // Only allow at most one field in a structure. This doesn't match the
+    // wording above, but follows gcc in situations with a field following an
+    // empty structure.
     if (!RD->isUnion()) {
       if (HadField)
         return false;

Modified: cfe/trunk/test/CodeGen/arm-arguments.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-arguments.c?rev=94796&r1=94795&r2=94796&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/arm-arguments.c (original)
+++ cfe/trunk/test/CodeGen/arm-arguments.c Thu Jan 28 21:22:29 2010
@@ -92,3 +92,30 @@
 // APCS-GNU: define arm_apcscc void @f16()
 // AAPCS: define arm_aapcscc void @f16()
 void f16(struct s8 a0) {}
+
+// APCS-GNU: define arm_apcscc i32 @f17()
+// AAPCS: define arm_aapcscc i32 @f17()
+struct s17 { short f0 : 13; char f1 : 4; };
+struct s17 f17(void) {}
+
+// APCS-GNU: define arm_apcscc i32 @f18()
+// AAPCS: define arm_aapcscc i32 @f18()
+struct s18 { short f0; char f1 : 4; };
+struct s18 f18(void) {}
+
+// APCS-GNU: define arm_apcscc void @f19(
+// APCS-GNU: struct.s19* noalias sret
+// AAPCS: define arm_aapcscc i32 @f19()
+struct s19 { int f0; struct s8 f1; };
+struct s19 f19(void) {}
+
+// APCS-GNU: define arm_apcscc void @f20(
+// APCS-GNU: struct.s20* noalias sret
+// AAPCS: define arm_aapcscc i32 @f20()
+struct s20 { struct s8 f1; int f0; };
+struct s20 f20(void) {}
+
+// APCS-GNU: define arm_apcscc i32 @f21()
+// AAPCS: define arm_aapcscc i32 @f21()
+struct s21 { struct {} f1; int f0 : 4; };
+struct s21 f21(void) {}





More information about the cfe-commits mailing list