diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -51,6 +51,10 @@ foo: asm goto ("# %0 %1"::"i"(&&foo)::foo); +- ``__builtin_object_size`` now adds the ``sizeof`` the elements specified in + designated initializers of flexible array members. This change is more + consistent with the behavior of GCC. + C++ Specific Potentially Breaking Changes ----------------------------------------- - Clang won't search for coroutine_traits in std::experimental namespace any more. diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11732,7 +11732,14 @@ auto CheckedHandleSizeof = [&](QualType Ty, CharUnits &Result) { if (Ty.isNull() || Ty->isIncompleteType() || Ty->isFunctionType()) return false; - return HandleSizeof(Info, ExprLoc, Ty, Result); + bool Ret = HandleSizeof(Info, ExprLoc, Ty, Result); + if (Ty->isStructureType() && + Ty->getAsStructureType()->getDecl()->hasFlexibleArrayMember()) { + const auto *VD = + cast(LVal.getLValueBase().get()); + Result += VD->getFlexibleArrayInitChars(Info.Ctx); + } + return Ret; }; // We want to evaluate the size of the entire object. This is a valid fallback diff --git a/clang/test/CodeGen/object-size.c b/clang/test/CodeGen/object-size.c --- a/clang/test/CodeGen/object-size.c +++ b/clang/test/CodeGen/object-size.c @@ -525,6 +525,16 @@ gi = OBJECT_SIZE_BUILTIN(&dsv[9].snd[0], 1); } +// CHECK-LABEL: @test32 +static struct DynStructVar D = { + .fst = {}, + .snd = { 0, 1, 2, }, +}; +unsigned long test32(void) { + // CHECK: ret i64 19 + return __builtin_object_size(&D, 1); +} + // CHECK-LABEL: @PR30346 void PR30346(void) { struct sa_family_t {};