From: Steve Naroff Date: Mon, 27 Aug 2007 15:30:22 +0000 (+0000) Subject: Replaced ASTContext::maxFloatingType() with ASTContext::compareFloatingType(). X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fb0d49669aa370b4c0993c5cee60275ef9fd6518;p=clang Replaced ASTContext::maxFloatingType() with ASTContext::compareFloatingType(). Changed Sema::UsualArithmeticConversions to use the new API. This fixes the following case... _Complex double X; double y; void foo() { X = X + y; } [dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang complex.c -parse-ast-dump Read top-level variable decl: 'X' Read top-level variable decl: 'y' void foo() (CompoundStmt 0x2605cc0 (BinaryOperator 0x2605ca0 '_Complex double' '=' (DeclRefExpr 0x2605c10 '_Complex double' Decl='X' 0x2605ab0) (BinaryOperator 0x2605c80 '_Complex double' '+' (DeclRefExpr 0x2605c30 '_Complex double' Decl='X' 0x2605ab0) (ImplicitCastExpr 0x2605c70 '_Complex double' (DeclRefExpr 0x2605c50 'double' Decl='y' 0x2605ae0))))) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41483 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index b0b963c4c8..4b79582e52 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -710,9 +710,15 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain( assert(0 && "getFloatingTypeOfSizeWithinDomain(): illegal domain"); } -// maxFloatingType - handles the simple case, both operands are floats. -QualType ASTContext::maxFloatingType(QualType lt, QualType rt) { - return getFloatingRank(lt) > getFloatingRank(rt) ? lt : rt; +/// compareFloatingType - Handles 3 different combos: +/// float/float, float/complex, complex/complex. +/// If lt > rt, return 1. If lt == rt, return 0. If lt < rt, return -1. +int ASTContext::compareFloatingType(QualType lt, QualType rt) { + if (getFloatingRank(lt) == getFloatingRank(rt)) + return 0; + if (getFloatingRank(lt) > getFloatingRank(rt)) + return 1; + return -1; } // maxIntegerType - Returns the highest ranked integer type. Handles 3 case: diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 9033ee917f..6cabbda8e2 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -821,16 +821,26 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, // real or complex domain, to the precision of the other type. For example, // when combining a "long double" with a "double _Complex", the // "double _Complex" is promoted to "long double _Complex". - if (Context.maxFloatingType(lhs, rhs) == lhs) { - // The left side is bigger, convert rhs within it's domain. + int result = Context.compareFloatingType(lhs, rhs); + + if (result > 0) { // The left side is bigger, convert rhs. QualType tMax = Context.getFloatingTypeOfSizeWithinDomain(lhs, rhs); if (!isCompAssign) promoteExprToType(rhsExpr, tMax); return tMax; } - // The right side is bigger, convert lhs within it's domain. - QualType tMax = Context.getFloatingTypeOfSizeWithinDomain(rhs, lhs); - if (!isCompAssign) promoteExprToType(lhsExpr, tMax); - return tMax; + if (result < 0) { // The right side is bigger, convert lhs. + QualType tMax = Context.getFloatingTypeOfSizeWithinDomain(rhs, lhs); + if (!isCompAssign) promoteExprToType(lhsExpr, tMax); + return tMax; + } + // The floating point types were ranked equally. + if (lhs->isComplexType()) { // handle "_Complex double, double". + if (!isCompAssign) promoteExprToType(rhsExpr, lhs); + return lhs; + } + // The right side is complex, handle "double, _Complex double". + if (!isCompAssign) promoteExprToType(lhsExpr, rhs); + return rhs; } // Now handle "real" floating types (i.e. float, double, long double). if (lhs->isRealFloatingType() || rhs->isRealFloatingType()) { @@ -845,12 +855,17 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, } // We have two real floating types, float/complex combos were handled above. // Convert the smaller operand to the bigger result. - if (Context.maxFloatingType(lhs, rhs) == lhs) { // convert the rhs + int result = Context.compareFloatingType(lhs, rhs); + + if (result > 0) { // convert the rhs if (!isCompAssign) promoteExprToType(rhsExpr, lhs); return lhs; } - if (!isCompAssign) promoteExprToType(lhsExpr, rhs); // convert the lhs - return rhs; + if (result < 0) { // convert the lhs + if (!isCompAssign) promoteExprToType(lhsExpr, rhs); // convert the lhs + return rhs; + } + assert(0 && "Sema::UsualArithmeticConversions(): illegal float comparison"); } // Finally, we have two differing integer types. if (Context.maxIntegerType(lhs, rhs) == lhs) { // convert the rhs diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 431d298471..2bfc6af89a 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -160,9 +160,10 @@ public: /// different type combos: unsigned/unsigned, signed/signed, signed/unsigned. static QualType maxIntegerType(QualType lhs, QualType rhs); - /// maxFloatingType - Returns the highest ranked float type. Handles 3 - /// different combos: float/float, float/complex, complex/complex. - static QualType maxFloatingType(QualType lt, QualType rt); + /// compareFloatingType - Handles 3 different combos: + /// float/float, float/complex, complex/complex. + /// If lt > rt, return 1. If lt == rt, return 0. If lt < rt, return -1. + static int compareFloatingType(QualType lt, QualType rt); /// getFloatingTypeOfSizeWithinDomain - Returns a real floating /// point or a complex type (based on typeDomain/typeSize).