[llvm-commits] [llvm-gcc-4.2] r54503 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Dale Johannesen dalej at apple.com
Thu Aug 7 20:35:04 PDT 2008


Author: johannes
Date: Thu Aug  7 22:35:02 2008
New Revision: 54503

URL: http://llvm.org/viewvc/llvm-project?rev=54503&view=rev
Log:
Fix a case where an initializer must add explicit
padding at the end of a struct (see commment).


Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=54503&r1=54502&r2=54503&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Aug  7 22:35:02 2008
@@ -6708,7 +6708,7 @@
 
     // Decode the field's value.
     Constant *Val = Convert(elt_value);
-   
+
     // If the field is a bitfield, it could be spread across multiple fields and
     // may start at some bit offset.
     if (isBitfield(Field)) {
@@ -6717,7 +6717,7 @@
       // If not, things are much simpler.
       unsigned int FieldNo = GetFieldIndex(Field);
       assert(FieldNo < ResultElts.size() && "Invalid struct field number!");
-     
+
       // Example: struct X { int A; char C[]; } x = { 4, "foo" };
       assert((TYPE_SIZE(getDeclaredType(Field)) ||
              (FieldNo == ResultElts.size()-1 &&
@@ -6751,7 +6751,34 @@
       ResultElts[i] = Constant::getNullValue(STy->getElementType(i));
   }
 
-  return ConstantStruct::get(ResultElts, STy->isPacked());
+  // The type we're going to build for the initializer is not necessarily the
+  // same as the type of the struct.  In cases where there is a union field.
+  // it is possible for the size and/or alignment of the two structs to differ,
+  // in which case we need some explicit padding.
+  Constant *retval = ConstantStruct::get(ResultElts, STy->isPacked());
+  const Type *NewSTy = retval->getType();
+
+  unsigned oldLLVMSize = getTargetData().getABITypeSize(STy);
+  unsigned oldLLVMAlign = getTargetData().getABITypeAlignment(STy);
+  oldLLVMSize = ((oldLLVMSize+oldLLVMAlign-1)/oldLLVMAlign)*oldLLVMAlign;
+
+  unsigned newLLVMSize = getTargetData().getABITypeSize(NewSTy);
+  unsigned newLLVMAlign = getTargetData().getABITypeAlignment(NewSTy);
+  newLLVMSize = ((newLLVMSize+newLLVMAlign-1)/newLLVMAlign)*newLLVMAlign;
+
+  // oldSize < newSize occurs legitimately when we don't know the size of
+  // the struct.
+  if (newLLVMSize < oldLLVMSize) {
+    const Type *FillTy;
+    if (oldLLVMSize - newLLVMSize == 1)
+      FillTy = Type::Int8Ty;
+    else
+      FillTy = ArrayType::get(Type::Int8Ty, oldLLVMSize - newLLVMSize);
+    ResultElts.push_back(Constant::getNullValue(FillTy));
+    retval = ConstantStruct::get(ResultElts, STy->isPacked());
+  }
+
+  return retval;
 }
 
 Constant *TreeConstantToLLVM::ConvertUnionCONSTRUCTOR(tree exp) {





More information about the llvm-commits mailing list