Skip to content

Commit dc8f0df

Browse files
committed
Use 'offsetof(struct s, array) + p->count * sizeof(*p->array)' instead of sizeof, which could emit an erroneous answer when alignment and padding are taken into account.
1 parent 82588c3 commit dc8f0df

File tree

1 file changed

+9
-10
lines changed

1 file changed

+9
-10
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -877,14 +877,14 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
877877
// 2) bdos of the whole struct, including the flexible array:
878878
//
879879
// __builtin_dynamic_object_size(p, 1) ==
880-
// sizeof(*p) + p->count * sizeof(*p->array)
880+
// offsetof(struct s, array) + p->count * sizeof(*p->array)
881881
//
882882
if (const ValueDecl *CountedByFD = FindCountedByField(E)) {
883883
// Find the flexible array member.
884+
ASTContext &Ctx = getContext();
884885
const RecordDecl *OuterRD =
885886
CountedByFD->getDeclContext()->getOuterLexicalRecordContext();
886-
const ValueDecl *FAM =
887-
FindFlexibleArrayMemberField(getContext(), OuterRD);
887+
const ValueDecl *FAM = FindFlexibleArrayMemberField(Ctx, OuterRD);
888888

889889
// Find the outer struct expr (i.e. p in p->a.b.c.d).
890890
const Expr *CountedByExpr = BuildCountedByFieldExpr(E, CountedByFD);
@@ -894,9 +894,8 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
894894
EmitAnyExprToTemp(CountedByExpr).getScalarVal();
895895

896896
// Get the size of the flexible array member's base type.
897-
const auto *ArrayTy = getContext().getAsArrayType(FAM->getType());
898-
CharUnits Size =
899-
getContext().getTypeSizeInChars(ArrayTy->getElementType());
897+
const auto *ArrayTy = Ctx.getAsArrayType(FAM->getType());
898+
CharUnits Size = Ctx.getTypeSizeInChars(ArrayTy->getElementType());
900899
llvm::Constant *ArraySize =
901900
llvm::ConstantInt::get(CountedByInstr->getType(), Size.getQuantity());
902901

@@ -905,10 +904,10 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
905904

906905
if (const auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) {
907906
// The whole struct is specificed in the __bdos.
908-
QualType StructTy = DRE->getType()->getPointeeType();
909-
llvm::Value *StructSize = ConstantInt::get(
910-
ResType, getContext().getTypeSizeInChars(StructTy).getQuantity(),
911-
true);
907+
CharUnits FAMOffset = Ctx.toCharUnitsFromBits(Ctx.getFieldOffset(FAM));
908+
llvm::Value *StructSize =
909+
ConstantInt::get(ResType, FAMOffset.getQuantity(), true);
910+
912911
ObjectSize = Builder.CreateAdd(StructSize, ObjectSize);
913912
}
914913

0 commit comments

Comments
 (0)