@@ -1235,6 +1235,8 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
12351235 // size_t flexible_array_member_size =
12361236 // count * flexible_array_member_base_size;
12371237 //
1238+ // if (flexible_array_member_size < 0)
1239+ // return 0;
12381240 // return flexible_array_member_size;
12391241 //
12401242 // 2) '&ptr->array[idx]':
@@ -1248,6 +1250,8 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
12481250 //
12491251 // size_t index_size = index * flexible_array_member_base_size;
12501252 //
1253+ // if (flexible_array_member_size < 0 || index < 0)
1254+ // return 0;
12511255 // return flexible_array_member_size - index_size;
12521256 //
12531257 // 3) '&ptr->field':
@@ -1262,7 +1266,9 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
12621266 // size_t field_offset = offsetof (struct s, field);
12631267 // size_t offset_diff = struct_size - field_offset;
12641268 //
1265- // return flexible_array_member_size + offset_diff;
1269+ // if (flexible_array_member_size < 0)
1270+ // return 0;
1271+ // return flexible_array_member_size;
12661272 //
12671273 // 4) '&ptr->field_array[idx]':
12681274 //
@@ -1280,6 +1286,8 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
12801286 //
12811287 // size_t offset_diff = sizeof_struct - field_offset;
12821288 //
1289+ // if (flexible_array_member_size < 0 || index < 0)
1290+ // return 0;
12831291 // return offset_diff + flexible_array_member_size;
12841292
12851293 QualType CountTy = CountFD->getType();
@@ -1302,13 +1310,13 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
13021310 Value *Index = nullptr;
13031311 if (Idx) {
13041312 bool IdxSigned = Idx->getType()->isSignedIntegerType();
1305- Index = EmitAnyExprToTemp (Idx).getScalarVal( );
1313+ Index = EmitScalarExpr (Idx);
13061314 Index = Builder.CreateIntCast(Index, ResType, IdxSigned, "index");
13071315 }
13081316
13091317 // size_t sizeof_struct = sizeof (struct s);
13101318 llvm::StructType *StructTy = getTypes().getCGRecordLayout(RD).getLLVMType();
1311- const llvm::DataLayout &Layout = Builder.GetInsertBlock()-> getDataLayout();
1319+ const llvm::DataLayout &Layout = CGM. getDataLayout();
13121320 TypeSize Size = Layout.getTypeSizeInBits(StructTy);
13131321 Value *SizeofStruct =
13141322 llvm::ConstantInt::get(ResType, Size.getKnownMinValue() / CharWidth);
@@ -1350,6 +1358,9 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
13501358 // return flexible_array_member_size - index_size;
13511359 return CheckForNegative(Builder.CreateSub(
13521360 FlexibleArrayMemberSize, IndexSize, "result", !IsSigned, IsSigned));
1361+ } else { // Option (1) 'ptr->array'
1362+ // return flexible_array_member_size;
1363+ return CheckForNegative(FlexibleArrayMemberSize);
13531364 }
13541365 } else {
13551366 if (Idx) { // Option (4) '&ptr->field_array[idx]'
@@ -1381,11 +1392,6 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
13811392 Builder.CreateAdd(FlexibleArrayMemberSize, OffsetDiff, "result"));
13821393 }
13831394 }
1384-
1385- // Option (1) 'ptr->array'
1386-
1387- // return flexible_array_member_size;
1388- return CheckForNegative(FlexibleArrayMemberSize);
13891395}
13901396
13911397/// Returns a Value corresponding to the size of the given expression.
0 commit comments