From: David Majnemer Date: Sun, 19 Oct 2014 00:03:10 +0000 (+0000) Subject: CodeGen: ConstStructBuilder must verify packed constraints after padding X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9fd8cd1b673daf4ff485b01c1980d917f789ef81;p=clang CodeGen: ConstStructBuilder must verify packed constraints after padding Before, ConstStructBuilder::AppendBytes would check packed constraints prior to padding being added before the field's offset. However, adding this padding might force our struct to be packed. Because we wouldn't check *after* adding padding, ConstStructBuilder would be in an inconsistent state leading to a crash. This fixes PR21300. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@220153 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 421e7deccc..dd87dd4657 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -106,15 +106,6 @@ AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst) { 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; - } - if (AlignedNextFieldOffsetInChars < FieldOffsetInChars) { // We need to append padding. AppendPadding(FieldOffsetInChars - NextFieldOffsetInChars); @@ -122,6 +113,16 @@ 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(); + AlignedNextFieldOffsetInChars = NextFieldOffsetInChars; } diff --git a/test/CodeGen/const-init.c b/test/CodeGen/const-init.c index 7d7ccae370..ccc6604c45 100644 --- a/test/CodeGen/const-init.c +++ b/test/CodeGen/const-init.c @@ -159,3 +159,14 @@ void g29() { static int b[1] = { "asdf" }; // expected-warning {{incompatible pointer to integer conversion initializing 'int' with an expression of type 'char [5]'}} static int c[1] = { L"a" }; } + +// PR21300 +void g30() { +#pragma pack(1) + static struct { + int : 1; + int x; + } a = {}; + // CHECK: @g30.a = internal global %struct.anon.1 <{ i8 undef, i32 0 }>, align 1 +#pragma pack() +}