nickdesaulniers created this revision. Herald added a project: All. nickdesaulniers requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
As reported by @kees, GCC treats __builtin_object_size of structures containing flexible array members (aka arrays with incomplete type) not just as the sizeof the underlying type, but additionally the size of the members in a designated initializer list. Fixes: https://github.com/llvm/llvm-project/issues/62789 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D150892 Files: clang/lib/AST/ExprConstant.cpp clang/test/CodeGen/object-size.c Index: clang/test/CodeGen/object-size.c =================================================================== --- clang/test/CodeGen/object-size.c +++ clang/test/CodeGen/object-size.c @@ -531,9 +531,7 @@ .snd = { 0, 1, 2, }, }; unsigned long test32(void) { - // FIXME: GCC returns the sizeof the base type, plus the number of bytes from - // members of the initializer of the flexible array: 19. - // CHECK: ret i64 16 + // CHECK: ret i64 19 return __builtin_object_size(&D, 1); } Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ 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 = dyn_cast_or_null<VarDecl>( + LVal.getLValueBase().dyn_cast<const ValueDecl *>()); + Result += VD->getFlexibleArrayInitChars(Info.Ctx); + } + return Ret; }; // We want to evaluate the size of the entire object. This is a valid fallback
Index: clang/test/CodeGen/object-size.c =================================================================== --- clang/test/CodeGen/object-size.c +++ clang/test/CodeGen/object-size.c @@ -531,9 +531,7 @@ .snd = { 0, 1, 2, }, }; unsigned long test32(void) { - // FIXME: GCC returns the sizeof the base type, plus the number of bytes from - // members of the initializer of the flexible array: 19. - // CHECK: ret i64 16 + // CHECK: ret i64 19 return __builtin_object_size(&D, 1); } Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ 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 = dyn_cast_or_null<VarDecl>( + LVal.getLValueBase().dyn_cast<const ValueDecl *>()); + Result += VD->getFlexibleArrayInitChars(Info.Ctx); + } + return Ret; }; // We want to evaluate the size of the entire object. This is a valid fallback
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits