]> granicus.if.org Git - clang/commitdiff
Cleanup and fix an assert that was mis-firing.
authorChandler Carruth <chandlerc@gmail.com>
Sun, 9 Dec 2012 10:33:27 +0000 (10:33 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sun, 9 Dec 2012 10:33:27 +0000 (10:33 +0000)
Note that there is no test suite update. This was found by a couple of
tests failing when the test suite was run on a powerpc64 host (thanks
Roman!). The tests don't specify a triple, which might seem surprising
for a codegen test. But in fact, these tests don't even inspect their
output. Not at all. I could add a bunch of triples to these tests so
that we'd get the test coverage for normal builds, but really someone
needs to go through and add actual *tests* to these tests. =[ The ones
in question are:

  test/CodeGen/bitfield-init.c
  test/CodeGen/union.c

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

lib/CodeGen/CGRecordLayoutBuilder.cpp

index 92c5672c732c5ae2f3cf669018a5f9704b9280b4..43088b4a2019fb6b0d49af6235e29b7fd651c7d9 100644 (file)
@@ -1063,15 +1063,23 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D,
     if (FD->getBitWidthValue(getContext()) == 0)
       continue;
 
-      unsigned FieldNo = RL->getLLVMFieldNo(FD);
     const CGBitFieldInfo &Info = RL->getBitFieldInfo(FD);
-    llvm::Type *ElementTy = ST->getTypeAtIndex(FieldNo);
+    llvm::Type *ElementTy = ST->getTypeAtIndex(RL->getLLVMFieldNo(FD));
+
     // Unions have overlapping elements dictating their layout, but for
     // non-unions we can verify that this section of the layout is the exact
-    // expected size. For unions we verify that the start is zero and the size
-    // is in-bounds.
+    // expected size.
     if (D->isUnion()) {
-      assert(Info.Offset == 0 && "Union bitfield with a non-zero offset");
+      // For unions we verify that the start is zero and the size
+      // is in-bounds. However, on BE systems, the offset may be non-zero, but
+      // the size + offset should match the storage size in that case as it
+      // "starts" at the back.
+      if (getDataLayout().isBigEndian())
+        assert((Info.Offset + Info.Size) == Info.StorageSize &&
+               "Big endian union bitfield does not end at the back");
+      else
+        assert(Info.Offset == 0 &&
+               "Little endian union bitfield with a non-zero offset");
       assert(Info.StorageSize <= SL->getSizeInBits() &&
              "Union not large enough for bitfield storage");
     } else {