[cfe-commits] r107621 - in /cfe/trunk: lib/CodeGen/CGExprConstant.cpp test/CodeGen/struct-init.c

Chris Lattner sabre at nondot.org
Mon Jul 5 11:03:30 PDT 2010


Author: lattner
Date: Mon Jul  5 13:03:30 2010
New Revision: 107621

URL: http://llvm.org/viewvc/llvm-project?rev=107621&view=rev
Log:
fix PR7564 a cast where the bitfield struct init code
wasn't handling array padding elements right.

Modified:
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/test/CodeGen/struct-init.c

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=107621&r1=107620&r2=107621&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Mon Jul  5 13:03:30 2010
@@ -190,11 +190,38 @@
       Tmp = Tmp.shl(8 - BitsInPreviousByte);
     }
 
-    // Or in the bits that go into the previous byte.
-    if (llvm::ConstantInt *Val = dyn_cast<llvm::ConstantInt>(Elements.back()))
+    // 'or' in the bits that go into the previous byte.
+    llvm::Value *LastElt = Elements.back();
+    if (llvm::ConstantInt *Val = dyn_cast<llvm::ConstantInt>(LastElt))
       Tmp |= Val->getValue();
-    else
-      assert(isa<llvm::UndefValue>(Elements.back()));
+    else {
+      assert(isa<llvm::UndefValue>(LastElt));
+      // If there is an undef field that we're adding to, it can either be a
+      // scalar undef (in which case, we just replace it with our field) or it
+      // is an array.  If it is an array, we have to pull one byte off the
+      // array so that the other undef bytes stay around.
+      if (!isa<llvm::IntegerType>(LastElt->getType())) {
+        // The undef padding will be a multibyte array, create a new smaller
+        // padding and then an hole for our i8 to get plopped into.
+        assert(isa<llvm::ArrayType>(LastElt->getType()) &&
+               "Expected array padding of undefs");
+        const llvm::ArrayType *AT = cast<llvm::ArrayType>(LastElt->getType());
+        assert(AT->getElementType()->isIntegerTy(8) &&
+               AT->getNumElements() != 0 &&
+               "Expected non-empty array padding of undefs");
+        
+        // Remove the padding array.
+        NextFieldOffsetInBytes -= AT->getNumElements();
+        Elements.pop_back();
+        
+        // Add the padding back in two chunks.
+        AppendPadding(AT->getNumElements()-1);
+        AppendPadding(1);
+        assert(isa<llvm::UndefValue>(Elements.back()) &&
+               Elements.back()->getType()->isIntegerTy(8) &&
+               "Padding addition didn't work right");
+      }
+    }
 
     Elements.back() = llvm::ConstantInt::get(CGM.getLLVMContext(), Tmp);
 

Modified: cfe/trunk/test/CodeGen/struct-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/struct-init.c?rev=107621&r1=107620&r2=107621&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/struct-init.c (original)
+++ cfe/trunk/test/CodeGen/struct-init.c Mon Jul  5 13:03:30 2010
@@ -10,3 +10,11 @@
 const zend_ini_entry ini_entries[] = {
   {  ((char*)&((zend_ini_entry*)0)->mh_arg1 - (char*)(void*)0)},
 };
+
+// PR7564
+struct GLGENH {
+  int : 27;
+  int EMHJAA : 1;
+};
+
+struct GLGENH ABHFBF = {1};





More information about the cfe-commits mailing list