@@ -1319,12 +1319,36 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
13191319
13201320 // size_t field_offset = offsetof (struct s, field);
13211321 Value *FieldOffset = nullptr;
1322+ llvm::ConstantInt *FieldBaseSize = nullptr;
13221323 if (FlexibleArrayMemberFD != FD) {
13231324 std::optional<int64_t> Offset = GetFieldOffset(Ctx, RD, FD);
13241325 if (!Offset)
13251326 return nullptr;
13261327 FieldOffset =
13271328 llvm::ConstantInt::get(ResType, *Offset / CharWidth, IsSigned);
1329+
1330+ if (Idx) {
1331+ // From option (4):
1332+ // size_t field_base_size = sizeof (*ptr->field_array);
1333+ if (!FieldTy->isArrayType())
1334+ // The field isn't an array. For example:
1335+ //
1336+ // struct {
1337+ // int count;
1338+ // char *string;
1339+ // int array[] __counted_by(count);
1340+ // } x;
1341+ //
1342+ // __builtin_dynamic_object_size(x.string[42], 0);
1343+ //
1344+ // If built with '-Wno-int-conversion', FieldTy won't be an array here.
1345+ return nullptr;
1346+
1347+ const ArrayType *ArrayTy = Ctx.getAsArrayType(FieldTy);
1348+ CharUnits BaseSize = Ctx.getTypeSizeInChars(ArrayTy->getElementType());
1349+ FieldBaseSize =
1350+ llvm::ConstantInt::get(ResType, BaseSize.getQuantity(), IsSigned);
1351+ }
13281352 }
13291353
13301354 // size_t count = (size_t) ptr->count;
@@ -1376,12 +1400,6 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
13761400 llvm::ConstantInt::get(ResType, Size.getKnownMinValue() / CharWidth);
13771401
13781402 if (Idx) { // Option (4) '&ptr->field_array[idx]'
1379- // size_t field_base_size = sizeof (*ptr->field_array);
1380- const ArrayType *ArrayTy = Ctx.getAsArrayType(FieldTy);
1381- CharUnits BaseSize = Ctx.getTypeSizeInChars(ArrayTy->getElementType());
1382- auto *FieldBaseSize =
1383- llvm::ConstantInt::get(ResType, BaseSize.getQuantity(), IsSigned);
1384-
13851403 // field_offset += index * field_base_size;
13861404 Value *Mul = Builder.CreateMul(Index, FieldBaseSize, "field_offset",
13871405 !IsSigned, IsSigned);
0 commit comments