summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-02-20 23:22:07 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-02-20 23:22:07 +0000
commit2b0d66df243a39608b80731451062fdd03efd701 (patch)
tree02709b2f94800d05d5aa37d02fb2940a75d151b8 /clang/lib
parentaf1465cef5e1e1b4d8cc5a516149c888b5a85b16 (diff)
downloadbcm5719-llvm-2b0d66df243a39608b80731451062fdd03efd701.tar.gz
bcm5719-llvm-2b0d66df243a39608b80731451062fdd03efd701.zip
Sema: Do not assert when dereferencing member pointer using virtual inheritance with an incomplete class type
The MS ABI requires that we determine the vbptr offset if have a virtual inheritance model. Instead, raise an error pointing to the diagnostic when this happens. This fixes PR18583. Differential Revision: http://llvm-reviews.chandlerc.com/D2842 llvm-svn: 201824
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGCXXABI.cpp15
-rw-r--r--clang/lib/CodeGen/CGCXXABI.h16
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp6
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp2
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp18
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp54
6 files changed, 53 insertions, 58 deletions
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index e9e34b0a1a4..72b84dc3e92 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -37,10 +37,9 @@ CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
}
-llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
- llvm::Value *&This,
- llvm::Value *MemPtr,
- const MemberPointerType *MPT) {
+llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(
+ CodeGenFunction &CGF, const Expr *E, llvm::Value *&This,
+ llvm::Value *MemPtr, const MemberPointerType *MPT) {
ErrorUnsupportedABI(CGF, "calls through member pointers");
const FunctionProtoType *FPT =
@@ -52,10 +51,10 @@ llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
return llvm::Constant::getNullValue(FTy->getPointerTo());
}
-llvm::Value *CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
- llvm::Value *Base,
- llvm::Value *MemPtr,
- const MemberPointerType *MPT) {
+llvm::Value *
+CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
+ llvm::Value *Base, llvm::Value *MemPtr,
+ const MemberPointerType *MPT) {
ErrorUnsupportedABI(CGF, "loads of member pointers");
llvm::Type *Ty = CGF.ConvertType(MPT->getPointeeType())->getPointerTo();
return llvm::Constant::getNullValue(Ty);
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h
index 6c89143c5fb..1112739cc18 100644
--- a/clang/lib/CodeGen/CGCXXABI.h
+++ b/clang/lib/CodeGen/CGCXXABI.h
@@ -122,17 +122,15 @@ public:
/// Load a member function from an object and a member function
/// pointer. Apply the this-adjustment and set 'This' to the
/// adjusted value.
- virtual llvm::Value *
- EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
- llvm::Value *&This,
- llvm::Value *MemPtr,
- const MemberPointerType *MPT);
+ virtual llvm::Value *EmitLoadOfMemberFunctionPointer(
+ CodeGenFunction &CGF, const Expr *E, llvm::Value *&This,
+ llvm::Value *MemPtr, const MemberPointerType *MPT);
/// Calculate an l-value from an object and a data member pointer.
- virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
- llvm::Value *Base,
- llvm::Value *MemPtr,
- const MemberPointerType *MPT);
+ virtual llvm::Value *
+ EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
+ llvm::Value *Base, llvm::Value *MemPtr,
+ const MemberPointerType *MPT);
/// Perform a derived-to-base, base-to-derived, or bitcast member
/// pointer conversion.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 40ca5889398..5ba748a88d4 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -390,7 +390,7 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
case SubobjectAdjustment::MemberPointerAdjustment: {
llvm::Value *Ptr = EmitScalarExpr(Adjustment.Ptr.RHS);
Object = CGM.getCXXABI().EmitMemberDataPointerAddress(
- *this, Object, Ptr, Adjustment.Ptr.MPT);
+ *this, E, Object, Ptr, Adjustment.Ptr.MPT);
break;
}
}
@@ -3239,8 +3239,8 @@ EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
const MemberPointerType *MPT
= E->getRHS()->getType()->getAs<MemberPointerType>();
- llvm::Value *AddV =
- CGM.getCXXABI().EmitMemberDataPointerAddress(*this, BaseV, OffsetV, MPT);
+ llvm::Value *AddV = CGM.getCXXABI().EmitMemberDataPointerAddress(
+ *this, E, BaseV, OffsetV, MPT);
return MakeAddrLValue(AddV, MPT->getPointeeType());
}
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 1e49d4ffd38..3f07e17b6c1 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -260,7 +260,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
// Ask the ABI to load the callee. Note that This is modified.
llvm::Value *Callee =
- CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*this, This, MemFnPtr, MPT);
+ CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*this, BO, This, MemFnPtr, MPT);
CallArgList Args;
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index bd3305e9a28..a9090ee13cf 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -71,11 +71,12 @@ public:
llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
+ const Expr *E,
llvm::Value *&This,
llvm::Value *MemFnPtr,
const MemberPointerType *MPT);
- llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
+ llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
llvm::Value *Base,
llvm::Value *MemPtr,
const MemberPointerType *MPT);
@@ -300,11 +301,9 @@ ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
///
/// If the member is non-virtual, memptr.ptr is the address of
/// the function to call.
-llvm::Value *
-ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
- llvm::Value *&This,
- llvm::Value *MemFnPtr,
- const MemberPointerType *MPT) {
+llvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
+ CodeGenFunction &CGF, const Expr *E, llvm::Value *&This,
+ llvm::Value *MemFnPtr, const MemberPointerType *MPT) {
CGBuilderTy &Builder = CGF.Builder;
const FunctionProtoType *FPT =
@@ -386,10 +385,9 @@ ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
/// Compute an l-value by applying the given pointer-to-member to a
/// base object.
-llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
- llvm::Value *Base,
- llvm::Value *MemPtr,
- const MemberPointerType *MPT) {
+llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
+ CodeGenFunction &CGF, const Expr *E, llvm::Value *Base, llvm::Value *MemPtr,
+ const MemberPointerType *MPT) {
assert(MemPtr->getType() == CGM.PtrDiffTy);
CGBuilderTy &Builder = CGF.Builder;
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 572bb098c93..57ad9fb1ad9 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -302,8 +302,8 @@ private:
/// \brief Performs a full virtual base adjustment. Used to dereference
/// pointers to members of virtual bases.
- llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const CXXRecordDecl *RD,
- llvm::Value *Base,
+ llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const Expr *E,
+ const CXXRecordDecl *RD, llvm::Value *Base,
llvm::Value *VirtualBaseAdjustmentOffset,
llvm::Value *VBPtrOffset /* optional */);
@@ -353,10 +353,10 @@ public:
llvm::Value *MemPtr,
const MemberPointerType *MPT);
- virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
- llvm::Value *Base,
- llvm::Value *MemPtr,
- const MemberPointerType *MPT);
+ virtual llvm::Value *
+ EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
+ llvm::Value *Base, llvm::Value *MemPtr,
+ const MemberPointerType *MPT);
virtual llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
const CastExpr *E,
@@ -366,9 +366,8 @@ public:
llvm::Constant *Src);
virtual llvm::Value *
- EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
- llvm::Value *&This,
- llvm::Value *MemPtr,
+ EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E,
+ llvm::Value *&This, llvm::Value *MemPtr,
const MemberPointerType *MPT);
private:
@@ -1687,11 +1686,9 @@ MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
// Returns an adjusted base cast to i8*, since we do more address arithmetic on
// it.
-llvm::Value *
-MicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF,
- const CXXRecordDecl *RD, llvm::Value *Base,
- llvm::Value *VBTableOffset,
- llvm::Value *VBPtrOffset) {
+llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
+ CodeGenFunction &CGF, const Expr *E, const CXXRecordDecl *RD,
+ llvm::Value *Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
CGBuilderTy &Builder = CGF.Builder;
Base = Builder.CreateBitCast(Base, CGM.Int8PtrTy);
llvm::BasicBlock *OriginalBB = 0;
@@ -1717,7 +1714,14 @@ MicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF,
// know the vbptr offset.
if (!VBPtrOffset) {
CharUnits offs = CharUnits::Zero();
- if (RD->getNumVBases())
+ if (!RD->hasDefinition()) {
+ DiagnosticsEngine &Diags = CGF.CGM.getDiags();
+ unsigned DiagID = Diags.getCustomDiagID(
+ DiagnosticsEngine::Error,
+ "member pointer representation requires a "
+ "complete class type for %0 to perform this expression");
+ Diags.Report(E->getExprLoc(), DiagID) << RD << E->getSourceRange();
+ } else if (RD->getNumVBases())
offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
VBPtrOffset = llvm::ConstantInt::get(CGM.IntTy, offs.getQuantity());
}
@@ -1738,11 +1742,9 @@ MicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF,
return AdjustedBase;
}
-llvm::Value *
-MicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
- llvm::Value *Base,
- llvm::Value *MemPtr,
- const MemberPointerType *MPT) {
+llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
+ CodeGenFunction &CGF, const Expr *E, llvm::Value *Base, llvm::Value *MemPtr,
+ const MemberPointerType *MPT) {
assert(MPT->isMemberDataPointer());
unsigned AS = Base->getType()->getPointerAddressSpace();
llvm::Type *PType =
@@ -1767,7 +1769,7 @@ MicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
}
if (VirtualBaseAdjustmentOffset) {
- Base = AdjustVirtualBase(CGF, RD, Base, VirtualBaseAdjustmentOffset,
+ Base = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
VBPtrOffset);
}
@@ -1975,11 +1977,9 @@ MicrosoftCXXABI::EmitMemberPointerConversion(const CastExpr *E,
return llvm::ConstantStruct::getAnon(Fields);
}
-llvm::Value *
-MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
- llvm::Value *&This,
- llvm::Value *MemPtr,
- const MemberPointerType *MPT) {
+llvm::Value *MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
+ CodeGenFunction &CGF, const Expr *E, llvm::Value *&This,
+ llvm::Value *MemPtr, const MemberPointerType *MPT) {
assert(MPT->isMemberFunctionPointer());
const FunctionProtoType *FPT =
MPT->getPointeeType()->castAs<FunctionProtoType>();
@@ -2010,7 +2010,7 @@ MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
}
if (VirtualBaseAdjustmentOffset) {
- This = AdjustVirtualBase(CGF, RD, This, VirtualBaseAdjustmentOffset,
+ This = AdjustVirtualBase(CGF, E, RD, This, VirtualBaseAdjustmentOffset,
VBPtrOffset);
}
OpenPOWER on IntegriCloud