diff options
author | Anders Carlsson <andersca@mac.com> | 2010-02-04 17:08:48 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-02-04 17:08:48 +0000 |
commit | 51591bed1050827c23691cf36e2e1621dfe08b00 (patch) | |
tree | c29ca56f4468dfe9f04cdbcb1676045cccb6c698 /lib/CodeGen/CGExprCXX.cpp | |
parent | 5bb0ddd10b07ecc0df43f0d5f50f0b9f10046426 (diff) |
Fix another pointer-to-member function miscompile, this time when trying to call a virtual member function.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95307 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGExprCXX.cpp | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 4253d18c39..ab54976e28 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -159,8 +159,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT), FPT->isVariadic()); - const llvm::Type *Int8PtrTy = - llvm::Type::getInt8Ty(VMContext)->getPointerTo(); + const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); // Get the member function pointer. llvm::Value *MemFnPtr = @@ -206,19 +205,20 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual); EmitBlock(FnVirtual); - const llvm::Type *VTableTy = - FTy->getPointerTo()->getPointerTo()->getPointerTo(); + const llvm::Type *VtableTy = + FTy->getPointerTo()->getPointerTo(); - llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy); - VTable = Builder.CreateLoad(VTable); + llvm::Value *Vtable = Builder.CreateBitCast(This, VtableTy->getPointerTo()); + Vtable = Builder.CreateLoad(Vtable); - VTable = Builder.CreateGEP(VTable, FnAsInt, "fn"); + Vtable = Builder.CreateBitCast(Vtable, Int8PtrTy); + llvm::Value *VtableOffset = + Builder.CreateSub(FnAsInt, llvm::ConstantInt::get(PtrDiffTy, 1)); - // Since the function pointer is 1 plus the virtual table offset, we - // subtract 1 by using a GEP. - VTable = Builder.CreateConstGEP1_64(VTable, (uint64_t)-1); + Vtable = Builder.CreateGEP(Vtable, VtableOffset, "fn"); + Vtable = Builder.CreateBitCast(Vtable, VtableTy); - llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "virtualfn"); + llvm::Value *VirtualFn = Builder.CreateLoad(Vtable, "virtualfn"); EmitBranch(FnEnd); EmitBlock(FnNonVirtual); |