From b29a74389190d649aeb96a5d1f949a3aaf4e744a Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 11 Oct 2014 11:03:30 +0000 Subject: [complex] Teach the other two binary operators on complex numbers (== and !=) to support mixed complex and real operand types. This requires removing an assert from SemaChecking, and adding support both to the constant evaluator and the code generator to synthesize the imaginary part when needed. This seemed somewhat cleaner than having just the comparison operators force real-to-complex conversions. I've added test cases for these operations. I'm really terrified that there were *no* tests in-tree which exercised this. This turned up when trying to build R after my change to the complex type lowering. llvm-svn: 219570 --- clang/lib/CodeGen/CGExprScalar.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'clang/lib/CodeGen') diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index abde51f29e4..ac6afe48453 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2754,6 +2754,7 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc, TestAndClearIgnoreResultAssign(); Value *Result; QualType LHSTy = E->getLHS()->getType(); + QualType RHSTy = E->getRHS()->getType(); if (const MemberPointerType *MPT = LHSTy->getAs()) { assert(E->getOpcode() == BO_EQ || E->getOpcode() == BO_NE); @@ -2761,7 +2762,7 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc, Value *RHS = CGF.EmitScalarExpr(E->getRHS()); Result = CGF.CGM.getCXXABI().EmitMemberPointerComparison( CGF, LHS, RHS, MPT, E->getOpcode() == BO_NE); - } else if (!LHSTy->isAnyComplexType()) { + } else if (!LHSTy->isAnyComplexType() && !RHSTy->isAnyComplexType()) { Value *LHS = Visit(E->getLHS()); Value *RHS = Visit(E->getRHS()); @@ -2849,10 +2850,27 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc, } else { // Complex Comparison: can only be an equality comparison. - CodeGenFunction::ComplexPairTy LHS = CGF.EmitComplexExpr(E->getLHS()); - CodeGenFunction::ComplexPairTy RHS = CGF.EmitComplexExpr(E->getRHS()); - - QualType CETy = LHSTy->getAs()->getElementType(); + CodeGenFunction::ComplexPairTy LHS, RHS; + QualType CETy; + if (auto *CTy = LHSTy->getAs()) { + LHS = CGF.EmitComplexExpr(E->getLHS()); + CETy = CTy->getElementType(); + } else { + LHS.first = Visit(E->getLHS()); + LHS.second = llvm::Constant::getNullValue(LHS.first->getType()); + CETy = LHSTy; + } + if (auto *CTy = RHSTy->getAs()) { + RHS = CGF.EmitComplexExpr(E->getRHS()); + assert(CGF.getContext().hasSameUnqualifiedType(CETy, + CTy->getElementType()) && + "The element types must always match."); + } else { + RHS.first = Visit(E->getRHS()); + RHS.second = llvm::Constant::getNullValue(RHS.first->getType()); + assert(CGF.getContext().hasSameUnqualifiedType(CETy, RHSTy) && + "The element types must always match."); + } Value *ResultR, *ResultI; if (CETy->isRealFloatingType()) { -- cgit v1.2.3