[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