Author: majnemer Date: Thu Feb 20 17:22:07 2014 New Revision: 201824 URL: http://llvm.org/viewvc/llvm-project?rev=201824&view=rev Log: 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 Modified: cfe/trunk/lib/CodeGen/CGCXXABI.cpp cfe/trunk/lib/CodeGen/CGCXXABI.h cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprCXX.cpp cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp Modified: cfe/trunk/lib/CodeGen/CGCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.cpp?rev=201824&r1=201823&r2=201824&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCXXABI.cpp Thu Feb 20 17:22:07 2014 @@ -37,10 +37,9 @@ CGCXXABI::ConvertMemberPointerType(const 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::EmitLoadOfMemberF 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); Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=201824&r1=201823&r2=201824&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCXXABI.h (original) +++ cfe/trunk/lib/CodeGen/CGCXXABI.h Thu Feb 20 17:22:07 2014 @@ -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. Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=201824&r1=201823&r2=201824&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Feb 20 17:22:07 2014 @@ -390,7 +390,7 @@ LValue CodeGenFunction::EmitMaterializeT 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 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()); } Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=201824&r1=201823&r2=201824&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Feb 20 17:22:07 2014 @@ -260,7 +260,7 @@ CodeGenFunction::EmitCXXMemberPointerCal // 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; Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=201824&r1=201823&r2=201824&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Thu Feb 20 17:22:07 2014 @@ -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( /// /// 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::EmitLoadOfMemberFunctionP /// 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; Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=201824&r1=201823&r2=201824&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Thu Feb 20 17:22:07 2014 @@ -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 // 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(CodeG // 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(CodeG 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::EmitMemberDataPointerAd } if (VirtualBaseAdjustmentOffset) { - Base = AdjustVirtualBase(CGF, RD, Base, VirtualBaseAdjustmentOffset, + Base = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset, VBPtrOffset); } @@ -1975,11 +1977,9 @@ MicrosoftCXXABI::EmitMemberPointerConver 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::EmitLoadOfMemberFunctio } if (VirtualBaseAdjustmentOffset) { - This = AdjustVirtualBase(CGF, RD, This, VirtualBaseAdjustmentOffset, + This = AdjustVirtualBase(CGF, E, RD, This, VirtualBaseAdjustmentOffset, VBPtrOffset); } Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp?rev=201824&r1=201823&r2=201824&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp (original) +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp Thu Feb 20 17:22:07 2014 @@ -1,7 +1,10 @@ // RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s +// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify +// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify // FIXME: Test x86_64 member pointers when codegen no longer asserts on records // with virtual bases. +#ifndef INCOMPLETE_VIRTUAL struct B1 { void foo(); int b; @@ -557,3 +560,15 @@ int *load_data(A *a, int A::*mp) { } } +#else +struct __virtual_inheritance A; +#ifdef MEMFUN +int foo(A *a, int (A::*mp)()) { + return (a->*mp)(); // expected-error{{requires a complete class type}} +} +#else +int foo(A *a, int A::*mp) { + return a->*mp; // expected-error{{requires a complete class type}} +} +#endif +#endif _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
