From 3a1737030e3c8d209987325c61dacb8e4a65123b Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Fri, 11 Dec 2009 09:26:29 +0000 Subject: [PATCH] Move the code for converting a member pointer to a bool so that it is usable for logical not. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91112 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExpr.cpp | 15 ++++++++++ lib/CodeGen/CGExprScalar.cpp | 30 ++------------------ test/CodeGenCXX/member-function-pointers.cpp | 15 ++++++++++ 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 0f351be01c..70fa004de8 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -38,6 +38,21 @@ llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(const llvm::Type *Ty, /// expression and compare the result against zero, returning an Int1Ty value. llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) { QualType BoolTy = getContext().BoolTy; + if (E->getType()->isMemberFunctionPointerType()) { + llvm::Value *Ptr = CreateTempAlloca(ConvertType(E->getType())); + EmitAggExpr(E, Ptr, /*VolatileDest=*/false); + + // Get the pointer. + llvm::Value *FuncPtr = Builder.CreateStructGEP(Ptr, 0, "src.ptr"); + FuncPtr = Builder.CreateLoad(FuncPtr); + + llvm::Value *IsNotNull = + Builder.CreateICmpNE(FuncPtr, + llvm::Constant::getNullValue(FuncPtr->getType()), + "tobool"); + + return IsNotNull; + } if (!E->getType()->isAnyComplexType()) return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 20da198a28..6f65638236 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -954,34 +954,8 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { case CastExpr::CK_FloatingCast: return EmitScalarConversion(Visit(E), E->getType(), DestTy); - case CastExpr::CK_MemberPointerToBoolean: { - const MemberPointerType* T = E->getType()->getAs(); - - if (T->getPointeeType()->isFunctionType()) { - // We have a member function pointer. - llvm::Value *Ptr = CGF.CreateTempAlloca(ConvertType(E->getType())); - - CGF.EmitAggExpr(E, Ptr, /*VolatileDest=*/false); - - // Get the pointer. - llvm::Value *FuncPtr = Builder.CreateStructGEP(Ptr, 0, "src.ptr"); - FuncPtr = Builder.CreateLoad(FuncPtr); - - llvm::Value *IsNotNull = - Builder.CreateICmpNE(FuncPtr, - llvm::Constant::getNullValue(FuncPtr->getType()), - "tobool"); - - return IsNotNull; - } - - // We have a regular member pointer. - Value *Ptr = Visit(const_cast(E)); - llvm::Value *IsNotNull = - Builder.CreateICmpNE(Ptr, CGF.CGM.EmitNullConstant(E->getType()), - "tobool"); - return IsNotNull; - } + case CastExpr::CK_MemberPointerToBoolean: + return CGF.EvaluateExprAsBool(E); } // Handle cases where the source is an non-complex type. diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp index 341c074e99..491ca5345a 100644 --- a/test/CodeGenCXX/member-function-pointers.cpp +++ b/test/CodeGenCXX/member-function-pointers.cpp @@ -113,3 +113,18 @@ namespace PR5718 { return f == g; } } + +namespace BoolMemberPointer { + struct A { }; + + bool f(void (A::*f)()) { + return !f; + } + + bool g(void (A::*f)()) { + if (!!f) + return true; + return false; + } +} +