summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MicrosoftCXXABI.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2017-12-13 21:53:04 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2017-12-13 21:53:04 +0000
commit5f4b5f89ed260041f1492e754cf5447f4f4123ed (patch)
tree27fa3c557b0a5603dc8d464c2ebceae348fef632 /lib/CodeGen/MicrosoftCXXABI.cpp
parente8ca256e5e3f0705a447f60d297e97457fd28438 (diff)
IRGen: When performing CFI checks, load vtable pointer from vbase when necessary.
Under the Microsoft ABI, it is possible for an object not to have a virtual table pointer of its own if all of its virtual functions were introduced by virtual bases. In that case, we need to load the vtable pointer from one of the virtual bases and perform the type check using its type. Differential Revision: https://reviews.llvm.org/D41036 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@320638 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MicrosoftCXXABI.cpp')
-rw-r--r--lib/CodeGen/MicrosoftCXXABI.cpp29
1 files changed, 22 insertions, 7 deletions
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index 97a7fbab9a..ffb3681c25 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -578,7 +578,7 @@ private:
return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
}
- std::pair<Address, llvm::Value *>
+ std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
performBaseAdjustment(CodeGenFunction &CGF, Address Value,
QualType SrcRecordTy);
@@ -745,6 +745,10 @@ public:
llvm::GlobalVariable *getThrowInfo(QualType T) override;
+ std::pair<llvm::Value *, const CXXRecordDecl *>
+ LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) override;
+
private:
typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
@@ -926,7 +930,7 @@ void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF,
/// We need to perform a generic polymorphic operation (like a typeid
/// or a cast), which requires an object with a vfptr. Adjust the
/// address to point to an object with a vfptr.
-std::pair<Address, llvm::Value *>
+std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
QualType SrcRecordTy) {
Value = CGF.Builder.CreateBitCast(Value, CGF.Int8PtrTy);
@@ -937,7 +941,8 @@ MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
// covers non-virtual base subobjects: a class with its own virtual
// functions would be a candidate to be a primary base.
if (Context.getASTRecordLayout(SrcDecl).hasExtendableVFPtr())
- return std::make_pair(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0));
+ return std::make_tuple(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0),
+ SrcDecl);
// Okay, one of the vbases must have a vfptr, or else this isn't
// actually a polymorphic class.
@@ -956,7 +961,7 @@ MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP(Value.getPointer(), Offset);
CharUnits VBaseAlign =
CGF.CGM.getVBaseAlignment(Value.getAlignment(), SrcDecl, PolymorphicBase);
- return std::make_pair(Address(Ptr, VBaseAlign), Offset);
+ return std::make_tuple(Address(Ptr, VBaseAlign), Offset, PolymorphicBase);
}
bool MicrosoftCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
@@ -987,7 +992,7 @@ llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
QualType SrcRecordTy,
Address ThisPtr,
llvm::Type *StdTypeInfoPtrTy) {
- std::tie(ThisPtr, std::ignore) =
+ std::tie(ThisPtr, std::ignore, std::ignore) =
performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
auto Typeid = emitRTtypeidCall(CGF, ThisPtr.getPointer()).getInstruction();
return CGF.Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
@@ -1011,7 +1016,8 @@ llvm::Value *MicrosoftCXXABI::EmitDynamicCastCall(
CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
llvm::Value *Offset;
- std::tie(This, Offset) = performBaseAdjustment(CGF, This, SrcRecordTy);
+ std::tie(This, Offset, std::ignore) =
+ performBaseAdjustment(CGF, This, SrcRecordTy);
llvm::Value *ThisPtr = This.getPointer();
Offset = CGF.Builder.CreateTrunc(Offset, CGF.Int32Ty);
@@ -1037,7 +1043,8 @@ llvm::Value *
MicrosoftCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF, Address Value,
QualType SrcRecordTy,
QualType DestTy) {
- std::tie(Value, std::ignore) = performBaseAdjustment(CGF, Value, SrcRecordTy);
+ std::tie(Value, std::ignore, std::ignore) =
+ performBaseAdjustment(CGF, Value, SrcRecordTy);
// PVOID __RTCastToVoid(
// PVOID inptr)
@@ -4244,3 +4251,11 @@ void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
};
CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(), Args);
}
+
+std::pair<llvm::Value *, const CXXRecordDecl *>
+MicrosoftCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) {
+ std::tie(This, std::ignore, RD) =
+ performBaseAdjustment(CGF, This, QualType(RD->getTypeForDecl(), 0));
+ return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD};
+}