@@ -1196,6 +1196,8 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
1196
1196
if (!CheckDynamicMemoryAllocation (S, OpPC))
1197
1197
return false ;
1198
1198
1199
+ DynamicAllocator &Allocator = S.getAllocator ();
1200
+
1199
1201
const Expr *Source = nullptr ;
1200
1202
const Block *BlockToDelete = nullptr ;
1201
1203
{
@@ -1212,6 +1214,21 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
1212
1214
while (Ptr.isBaseClass ())
1213
1215
Ptr = Ptr.getBase ();
1214
1216
1217
+ Source = Ptr.getDeclDesc ()->asExpr ();
1218
+ BlockToDelete = Ptr.block ();
1219
+
1220
+ // Check that new[]/delete[] or new/delete were used, not a mixture.
1221
+ const Descriptor *BlockDesc = BlockToDelete->getDescriptor ();
1222
+ if (std::optional<DynamicAllocator::Form> AllocForm =
1223
+ Allocator.getAllocationForm (Source)) {
1224
+ DynamicAllocator::Form DeleteForm =
1225
+ DeleteIsArrayForm ? DynamicAllocator::Form::Array
1226
+ : DynamicAllocator::Form::NonArray;
1227
+ if (!CheckNewDeleteForms (S, OpPC, *AllocForm, DeleteForm, BlockDesc,
1228
+ Source))
1229
+ return false ;
1230
+ }
1231
+
1215
1232
// For the non-array case, the types must match if the static type
1216
1233
// does not have a virtual destructor.
1217
1234
if (!DeleteIsArrayForm && Ptr.getType () != InitialType &&
@@ -1230,9 +1247,6 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
1230
1247
return false ;
1231
1248
}
1232
1249
1233
- Source = Ptr.getDeclDesc ()->asExpr ();
1234
- BlockToDelete = Ptr.block ();
1235
-
1236
1250
if (!CheckDeleteSource (S, OpPC, Source, Ptr))
1237
1251
return false ;
1238
1252
@@ -1266,24 +1280,14 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
1266
1280
if (!RunDestructors (S, OpPC, BlockToDelete))
1267
1281
return false ;
1268
1282
1269
- DynamicAllocator &Allocator = S.getAllocator ();
1270
- const Descriptor *BlockDesc = BlockToDelete->getDescriptor ();
1271
- std::optional<DynamicAllocator::Form> AllocForm =
1272
- Allocator.getAllocationForm (Source);
1273
-
1274
1283
if (!Allocator.deallocate (Source, BlockToDelete, S)) {
1275
1284
// Nothing has been deallocated, this must be a double-delete.
1276
1285
const SourceInfo &Loc = S.Current ->getSource (OpPC);
1277
1286
S.FFDiag (Loc, diag::note_constexpr_double_delete);
1278
1287
return false ;
1279
1288
}
1280
1289
1281
- assert (AllocForm);
1282
- DynamicAllocator::Form DeleteForm = DeleteIsArrayForm
1283
- ? DynamicAllocator::Form::Array
1284
- : DynamicAllocator::Form::NonArray;
1285
- return CheckNewDeleteForms (S, OpPC, *AllocForm, DeleteForm, BlockDesc,
1286
- Source);
1290
+ return true ;
1287
1291
}
1288
1292
1289
1293
void diagnoseEnumValue (InterpState &S, CodePtr OpPC, const EnumDecl *ED,
0 commit comments