From: Anders Carlsson Date: Sun, 16 Nov 2008 07:17:21 +0000 (+0000) Subject: Add the ability to evaluate comparison operators with floating point numbers as operands. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=286f85e791dda3634fee7f6c67f0ed92296c028f;p=clang Add the ability to evaluate comparison operators with floating point numbers as operands. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59408 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 87ee465174..08236836a7 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -529,8 +529,51 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { return false; } - if (!E->getLHS()->getType()->isIntegralType() || - !E->getRHS()->getType()->isIntegralType()) { + QualType LHSTy = E->getLHS()->getType(); + QualType RHSTy = E->getRHS()->getType(); + + if (LHSTy->isRealFloatingType() && + RHSTy->isRealFloatingType()) { + APFloat RHS(0.0), LHS(0.0); + + if (!EvaluateFloat(E->getRHS(), RHS, Info)) + return false; + + if (!EvaluateFloat(E->getLHS(), LHS, Info)) + return false; + + APFloat::cmpResult CR = LHS.compare(RHS); + + switch (E->getOpcode()) { + default: + assert(0 && "Invalid binary operator!"); + case BinaryOperator::LT: + Result = CR == APFloat::cmpLessThan; + break; + case BinaryOperator::GT: + Result = CR == APFloat::cmpGreaterThan; + break; + case BinaryOperator::LE: + Result = CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual; + break; + case BinaryOperator::GE: + Result = CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual; + break; + case BinaryOperator::EQ: + Result = CR == APFloat::cmpEqual; + break; + case BinaryOperator::NE: + Result = CR == APFloat::cmpGreaterThan || CR == APFloat::cmpLessThan; + break; + } + + Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); + Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); + return true; + } + + if (!LHSTy->isIntegralType() || + !RHSTy->isIntegralType()) { // We can't continue from here for non-integral types, and they // could potentially confuse the following operations. // FIXME: Deal with EQ and friends.