Fix a tail padding bug in the record layout builder code. The bug was found by an existing test.

llvm-svn: 77189
This commit is contained in:
Anders Carlsson 2009-07-27 14:55:54 +00:00
parent 729749d34d
commit b97a3ec4e7
2 changed files with 19 additions and 6 deletions

View File

@ -88,6 +88,8 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
AppendBytes(NumBytesToAppend); AppendBytes(NumBytesToAppend);
AlignmentAsLLVMStruct = std::max(AlignmentAsLLVMStruct, getTypeAlignment(Ty));
BitsAvailableInLastField = BitsAvailableInLastField =
getNextFieldOffsetInBytes() * 8 - (FieldOffset + FieldSize); getNextFieldOffsetInBytes() * 8 - (FieldOffset + FieldSize);
} }
@ -207,12 +209,22 @@ bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
} }
// Append tail padding if necessary. // Append tail padding if necessary.
if (Layout.getSize() / 8 > getNextFieldOffsetInBytes()) AppendTailPadding(Layout.getSize());
AppendPadding(getNextFieldOffsetInBytes(), AlignmentAsLLVMStruct);
return true; return true;
} }
void CGRecordLayoutBuilder::AppendTailPadding(uint64_t RecordSize) {
assert(RecordSize % 8 == 0 && "Invalid record size!");
uint64_t RecordSizeInBytes = RecordSize / 8;
assert(getNextFieldOffsetInBytes() <= RecordSizeInBytes && "Size mismatch!");
unsigned NumPadBytes = RecordSizeInBytes - getNextFieldOffsetInBytes();
AppendBytes(NumPadBytes);
}
void CGRecordLayoutBuilder::AppendField(uint64_t FieldOffsetInBytes, void CGRecordLayoutBuilder::AppendField(uint64_t FieldOffsetInBytes,
const llvm::Type *FieldTy) { const llvm::Type *FieldTy) {
AlignmentAsLLVMStruct = std::max(AlignmentAsLLVMStruct, AlignmentAsLLVMStruct = std::max(AlignmentAsLLVMStruct,
@ -256,10 +268,8 @@ void CGRecordLayoutBuilder::AppendBytes(uint64_t NumBytes) {
return; return;
const llvm::Type *Ty = llvm::Type::Int8Ty; const llvm::Type *Ty = llvm::Type::Int8Ty;
if (NumBytes > 1) { if (NumBytes > 1)
// FIXME: Use a VMContext.
Ty = llvm::ArrayType::get(Ty, NumBytes); Ty = llvm::ArrayType::get(Ty, NumBytes);
}
// Append the padding field // Append the padding field
AppendField(getNextFieldOffsetInBytes(), Ty); AppendField(getNextFieldOffsetInBytes(), Ty);
@ -294,7 +304,6 @@ CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types,
// FIXME: Once this works well enough, enable it. // FIXME: Once this works well enough, enable it.
return 0; return 0;
// FIXME: Use a VMContext.
const llvm::Type *Ty = llvm::StructType::get(Builder.FieldTypes, const llvm::Type *Ty = llvm::StructType::get(Builder.FieldTypes,
Builder.Packed); Builder.Packed);

View File

@ -111,6 +111,10 @@ class CGRecordLayoutBuilder {
/// AppendBytes - Append a given number of bytes to the record. /// AppendBytes - Append a given number of bytes to the record.
void AppendBytes(uint64_t NumBytes); void AppendBytes(uint64_t NumBytes);
/// AppendTailPadding - Append enough tail padding so that the type will have
/// the passed size.
void AppendTailPadding(uint64_t RecordSize);
/// getNextFieldOffsetInBytes - returns where the next field offset is. /// getNextFieldOffsetInBytes - returns where the next field offset is.
uint64_t getNextFieldOffsetInBytes() const; uint64_t getNextFieldOffsetInBytes() const;