diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index a95042514d8c30..322602606ebe9d 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -354,12 +354,17 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D, return GV; } +#if 0 + // FIXME: The following check doesn't handle flexible array members + // inside tail padding (which don't actually increase the size of + // the struct). #ifndef NDEBUG CharUnits VarSize = CGM.getContext().getTypeSizeInChars(D.getType()) + D.getFlexibleArrayInitChars(getContext()); CharUnits CstSize = CharUnits::fromQuantity( CGM.getDataLayout().getTypeAllocSize(Init->getType())); assert(VarSize == CstSize && "Emitted constant has unexpected size"); +#endif #endif // The initializer may differ in type from the global. Rewrite diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index dbbbf7fd554bc1..5184a363f18f5e 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4631,12 +4631,17 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, if (getLangOpts().CPlusPlus && !NeedsGlobalDtor) DelayedCXXInitPosition.erase(D); +#if 0 + // FIXME: The following check doesn't handle flexible array members + // inside tail padding (which don't actually increase the size of + // the struct). #ifndef NDEBUG CharUnits VarSize = getContext().getTypeSizeInChars(ASTTy) + InitDecl->getFlexibleArrayInitChars(getContext()); CharUnits CstSize = CharUnits::fromQuantity( getDataLayout().getTypeAllocSize(Init->getType())); assert(VarSize == CstSize && "Emitted constant has unexpected size"); +#endif #endif } } diff --git a/clang/test/CodeGen/flexible-array-init.c b/clang/test/CodeGen/flexible-array-init.c index 0dbf2331ba8ab3..5974d475f816be 100644 --- a/clang/test/CodeGen/flexible-array-init.c +++ b/clang/test/CodeGen/flexible-array-init.c @@ -5,3 +5,20 @@ struct { int x; int y[]; } a = { 1, 7, 11 }; struct { int x; int y[]; } b = { 1, { 13, 15 } }; // CHECK: @b ={{.*}} global { i32, [2 x i32] } { i32 1, [2 x i32] [i32 13, i32 15] } + +// sizeof(c) == 8, so this global should be at least 8 bytes. +struct { int x; char c; char y[]; } c = { 1, 2, { 13, 15 } }; +// CHECK: @c ={{.*}} global { i32, i8, [2 x i8] } { i32 1, i8 2, [2 x i8] c"\0D\0F" } + +// sizeof(d) == 8, so this global should be at least 8 bytes. +struct __attribute((packed, aligned(4))) { char a; int x; char z[]; } d = { 1, 2, { 13, 15 } }; +// CHECK: @d ={{.*}} <{ i8, i32, [2 x i8], i8 }> <{ i8 1, i32 2, [2 x i8] c"\0D\0F", i8 undef }>, + +// This global needs 9 bytes to hold all the flexible array members. +struct __attribute((packed, aligned(4))) { char a; int x; char z[]; } e = { 1, 2, { 13, 15, 17, 19 } }; +// CHECK: @e ={{.*}} <{ i8, i32, [4 x i8] }> <{ i8 1, i32 2, [4 x i8] c"\0D\0F\11\13" }> + +// FIXME: This global should be 6 bytes, not 8. Not likely to matter in most +// cases, but still a bug. +struct { int x; char y[]; } f = { 1, { 13, 15 } }; +// CHECK: @f ={{.*}} global { i32, [2 x i8] } { i32 1, [2 x i8] c"\0D\0F" }