diff options
author | Timm Baeder <tbaeder@redhat.com> | 2025-07-10 07:33:33 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-10 07:33:33 +0200 |
commit | 36cbd43ae8d5a5274ae3193b6383fff2ba9671f4 (patch) | |
tree | da81f8723356f411e8533539e63505cc53e91803 /clang/lib/AST/ByteCode | |
parent | 00a85e57049ee637a6089b2c696d5e37db8cd47b (diff) | |
download | llvm-36cbd43ae8d5a5274ae3193b6383fff2ba9671f4.zip llvm-36cbd43ae8d5a5274ae3193b6383fff2ba9671f4.tar.gz llvm-36cbd43ae8d5a5274ae3193b6383fff2ba9671f4.tar.bz2 |
[clang][bytecode] Check new/delete mismatch earlier (#147732)
This fixes a mismatch in diagnostic output with the current intepreter.
Diffstat (limited to 'clang/lib/AST/ByteCode')
-rw-r--r-- | clang/lib/AST/ByteCode/Interp.cpp | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 51cf0c5..be77657 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1196,6 +1196,8 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm, if (!CheckDynamicMemoryAllocation(S, OpPC)) return false; + DynamicAllocator &Allocator = S.getAllocator(); + const Expr *Source = nullptr; const Block *BlockToDelete = nullptr; { @@ -1212,6 +1214,21 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm, while (Ptr.isBaseClass()) Ptr = Ptr.getBase(); + Source = Ptr.getDeclDesc()->asExpr(); + BlockToDelete = Ptr.block(); + + // Check that new[]/delete[] or new/delete were used, not a mixture. + const Descriptor *BlockDesc = BlockToDelete->getDescriptor(); + if (std::optional<DynamicAllocator::Form> AllocForm = + Allocator.getAllocationForm(Source)) { + DynamicAllocator::Form DeleteForm = + DeleteIsArrayForm ? DynamicAllocator::Form::Array + : DynamicAllocator::Form::NonArray; + if (!CheckNewDeleteForms(S, OpPC, *AllocForm, DeleteForm, BlockDesc, + Source)) + return false; + } + // For the non-array case, the types must match if the static type // does not have a virtual destructor. if (!DeleteIsArrayForm && Ptr.getType() != InitialType && @@ -1230,9 +1247,6 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm, return false; } - Source = Ptr.getDeclDesc()->asExpr(); - BlockToDelete = Ptr.block(); - if (!CheckDeleteSource(S, OpPC, Source, Ptr)) return false; @@ -1266,11 +1280,6 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm, if (!RunDestructors(S, OpPC, BlockToDelete)) return false; - DynamicAllocator &Allocator = S.getAllocator(); - const Descriptor *BlockDesc = BlockToDelete->getDescriptor(); - std::optional<DynamicAllocator::Form> AllocForm = - Allocator.getAllocationForm(Source); - if (!Allocator.deallocate(Source, BlockToDelete, S)) { // Nothing has been deallocated, this must be a double-delete. const SourceInfo &Loc = S.Current->getSource(OpPC); @@ -1278,12 +1287,7 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm, return false; } - assert(AllocForm); - DynamicAllocator::Form DeleteForm = DeleteIsArrayForm - ? DynamicAllocator::Form::Array - : DynamicAllocator::Form::NonArray; - return CheckNewDeleteForms(S, OpPC, *AllocForm, DeleteForm, BlockDesc, - Source); + return true; } void diagnoseEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED, |