From acc7981883acd2dd9418eb56b5e7e49fa4ec143b Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sun, 16 Nov 2008 07:17:21 +0000 Subject: [PATCH] Add the ability to evaluate comparison operators with floating point numbers as operands. llvm-svn: 59408 --- clang/lib/AST/ExprConstant.cpp | 47 ++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 87ee4651748e..08236836a701 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/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.