aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-12-11 07:36:43 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-12-11 07:36:43 +0000
commitb81c786de58ce484230dc04f9a7c78bc48990106 (patch)
treef3bb1a5badf0f8805304ddb612b4ede97d8620ae /lib/CodeGen/CGExprScalar.cpp
parent2b87ae45e129b941d0a4d221c9d4842385a119bd (diff)
Fix for PR5718: implement equality comparisons for member function pointers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91108 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--lib/CodeGen/CGExprScalar.cpp29
1 files changed, 28 insertions, 1 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index dfa5b2026c..20da198a28 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1571,7 +1571,34 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc,
TestAndClearIgnoreResultAssign();
Value *Result;
QualType LHSTy = E->getLHS()->getType();
- if (!LHSTy->isAnyComplexType()) {
+ if (LHSTy->isMemberFunctionPointerType()) {
+ Value *LHSPtr = CGF.EmitAnyExprToTemp(E->getLHS()).getAggregateAddr();
+ Value *RHSPtr = CGF.EmitAnyExprToTemp(E->getRHS()).getAggregateAddr();
+ llvm::Value *LHSFunc = Builder.CreateStructGEP(LHSPtr, 0);
+ LHSFunc = Builder.CreateLoad(LHSFunc);
+ llvm::Value *RHSFunc = Builder.CreateStructGEP(RHSPtr, 0);
+ RHSFunc = Builder.CreateLoad(RHSFunc);
+ Value *ResultF = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+ LHSFunc, RHSFunc, "cmp.func");
+ Value *NullPtr = llvm::Constant::getNullValue(LHSFunc->getType());
+ Value *ResultNull = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+ LHSFunc, NullPtr, "cmp.null");
+ llvm::Value *LHSAdj = Builder.CreateStructGEP(LHSPtr, 1);
+ LHSAdj = Builder.CreateLoad(LHSAdj);
+ llvm::Value *RHSAdj = Builder.CreateStructGEP(RHSPtr, 1);
+ RHSAdj = Builder.CreateLoad(RHSAdj);
+ Value *ResultA = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+ LHSAdj, RHSAdj, "cmp.adj");
+ if (E->getOpcode() == BinaryOperator::EQ) {
+ Result = Builder.CreateOr(ResultNull, ResultA, "or.na");
+ Result = Builder.CreateAnd(Result, ResultF, "and.f");
+ } else {
+ assert(E->getOpcode() == BinaryOperator::NE &&
+ "Member pointer comparison other than == or != ?");
+ Result = Builder.CreateAnd(ResultNull, ResultA, "and.na");
+ Result = Builder.CreateOr(Result, ResultF, "or.f");
+ }
+ } else if (!LHSTy->isAnyComplexType()) {
Value *LHS = Visit(E->getLHS());
Value *RHS = Visit(E->getRHS());