diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-10-19 23:40:06 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-10-19 23:40:06 +0000 |
commit | 8e133965c8ff3063a50c118c3797a5d7bb4fc75f (patch) | |
tree | 26366f3cc049f98621e3189eb5d9af0ed1e5cdd3 /clang/lib/CodeGen/CGExprConstant.cpp | |
parent | c4df33be5af658c3ef5316bb6dc4cb370ec9a138 (diff) | |
download | bcm5719-llvm-8e133965c8ff3063a50c118c3797a5d7bb4fc75f.tar.gz bcm5719-llvm-8e133965c8ff3063a50c118c3797a5d7bb4fc75f.zip |
CodeGen: ConstStructBuilder must verify packed constraints after padding
This reverts commit r220169 which reverted r220153. However, it also
contains additional changes:
- We may need to add padding *after* we've packed the struct. This
occurs when the aligned next field offset is greater than the new
field's offset. When this occurs, we make the struct packed.
*However*, once packed the next field offset might be less than the
new feild's offset. It is in this case that we might further pad the
struct.
- We would pad structs which were perfectly sized! This behavior is
immensely old. This behavior came from blindly subtracting
NextFieldOffsetInChars from RecordSize. This doesn't take into
account the fact that the struct might have a greater overall
alignment than the last field.
llvm-svn: 220175
Diffstat (limited to 'clang/lib/CodeGen/CGExprConstant.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 421e7deccc3..088a5d08b9b 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -104,16 +104,7 @@ AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst) { // Round up the field offset to the alignment of the field type. CharUnits AlignedNextFieldOffsetInChars = - NextFieldOffsetInChars.RoundUpToAlignment(FieldAlignment); - - if (AlignedNextFieldOffsetInChars > FieldOffsetInChars) { - assert(!Packed && "Alignment is wrong even with a packed struct!"); - - // Convert the struct to a packed struct. - ConvertStructToPacked(); - - AlignedNextFieldOffsetInChars = NextFieldOffsetInChars; - } + NextFieldOffsetInChars.RoundUpToAlignment(FieldAlignment); if (AlignedNextFieldOffsetInChars < FieldOffsetInChars) { // We need to append padding. @@ -122,6 +113,24 @@ AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst) { assert(NextFieldOffsetInChars == FieldOffsetInChars && "Did not add enough padding!"); + AlignedNextFieldOffsetInChars = + NextFieldOffsetInChars.RoundUpToAlignment(FieldAlignment); + } + + if (AlignedNextFieldOffsetInChars > FieldOffsetInChars) { + assert(!Packed && "Alignment is wrong even with a packed struct!"); + + // Convert the struct to a packed struct. + ConvertStructToPacked(); + + // After we pack the struct, we may need to insert padding. + if (NextFieldOffsetInChars < FieldOffsetInChars) { + // We need to append padding. + AppendPadding(FieldOffsetInChars - NextFieldOffsetInChars); + + assert(NextFieldOffsetInChars == FieldOffsetInChars && + "Did not add enough padding!"); + } AlignedNextFieldOffsetInChars = NextFieldOffsetInChars; } @@ -486,10 +495,14 @@ llvm::Constant *ConstStructBuilder::Finalize(QualType Ty) { // No tail padding is necessary. } else { // Append tail padding if necessary. - AppendTailPadding(LayoutSizeInChars); - CharUnits LLVMSizeInChars = - NextFieldOffsetInChars.RoundUpToAlignment(LLVMStructAlignment); + NextFieldOffsetInChars.RoundUpToAlignment(LLVMStructAlignment); + + if (LLVMSizeInChars != LayoutSizeInChars) + AppendTailPadding(LayoutSizeInChars); + + LLVMSizeInChars = + NextFieldOffsetInChars.RoundUpToAlignment(LLVMStructAlignment); // Check if we need to convert the struct to a packed struct. if (NextFieldOffsetInChars <= LayoutSizeInChars && @@ -501,7 +514,10 @@ llvm::Constant *ConstStructBuilder::Finalize(QualType Ty) { "Converting to packed did not help!"); } - assert(LayoutSizeInChars == NextFieldOffsetInChars && + LLVMSizeInChars = + NextFieldOffsetInChars.RoundUpToAlignment(LLVMStructAlignment); + + assert(LayoutSizeInChars == LLVMSizeInChars && "Tail padding mismatch!"); } |