Skip to content

Commit

Permalink
Fix global ::delete on virtual object
Browse files Browse the repository at this point in the history
Using `::delete` would fail because
`ItaniumCXXABI::emitVirtualObjectDelete` used the wrong offset (-2) into
the vtable to find the complete-object pointer.

Example (triggers address sanitizer):

```
struct Base {
        virtual ~Base() {}
};

struct Derived : Base {};

int main() {
        Derived* derived = ::new Derived();
        ::delete derived;
}
```
  • Loading branch information
DutChen18 committed May 1, 2024
1 parent 55a4f9a commit 5b48af3
Showing 1 changed file with 26 additions and 7 deletions.
33 changes: 26 additions & 7 deletions clang/lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1282,16 +1282,35 @@ void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
// Derive the complete-object pointer, which is what we need
// to pass to the deallocation function.

// Grab the vtable pointer as an intptr_t*.
auto *ClassDecl =
cast<CXXRecordDecl>(ElementType->castAs<RecordType>()->getDecl());
llvm::Value *VTable =
CGF.GetVTablePtr(Ptr, CGF.IntPtrTy->getPointerTo(), ClassDecl);
llvm::Value *Offset;

// Track back to entry -2 and pull out the offset there.
llvm::Value *OffsetPtr = CGF.Builder.CreateConstInBoundsGEP1_64(
CGF.IntPtrTy, VTable, -2, "complete-offset.ptr");
llvm::Value *Offset = CGF.Builder.CreateAlignedLoad(CGF.IntPtrTy, OffsetPtr, CGF.getPointerAlign());
if (!CGM.getTarget().isByteAddressable()) {
bool asmjs = ClassDecl->hasAttr<AsmJSAttr>();

if (asmjs) {
llvm::Type *VTableType =
CGM.getTypes().GetSecondaryVTableType(ClassDecl);
Address VTable = Address(
CGF.GetVTablePtr(Ptr, VTableType->getPointerTo(), ClassDecl),
VTableType, Ptr.getAlignment());
Address Tmp = CGF.Builder.CreateStructGEP(VTable, 0);
Offset = CGF.Builder.CreateLoad(Tmp, "complete-offset.ptr");
} else {
Offset = llvm::ConstantInt::get(CGM.IntPtrTy, 0);
}
} else {
// Grab the vtable pointer as an intptr_t*.
llvm::Value *VTable =
CGF.GetVTablePtr(Ptr, CGF.IntPtrTy->getPointerTo(), ClassDecl);

// Track back to entry -2 and pull out the offset there.
llvm::Value *OffsetPtr = CGF.Builder.CreateConstInBoundsGEP1_64(
CGF.IntPtrTy, VTable, -2, "complete-offset.ptr");
Offset = CGF.Builder.CreateAlignedLoad(CGF.IntPtrTy, OffsetPtr,
CGF.getPointerAlign());
}

// Apply the offset.
llvm::Value *CompletePtr =
Expand Down

0 comments on commit 5b48af3

Please sign in to comment.