diff options
author | Steve Naroff <snaroff@apple.com> | 2007-08-27 15:30:22 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2007-08-27 15:30:22 +0000 |
commit | 7af82d462ac2d1960a6e24fb6e6f4297c9e06820 (patch) | |
tree | 93a2521d00e673c650ddb7954980e116e072be30 | |
parent | 032d89828e148b846e90e5ba498779adf26d8958 (diff) | |
download | bcm5719-llvm-7af82d462ac2d1960a6e24fb6e6f4297c9e06820.tar.gz bcm5719-llvm-7af82d462ac2d1960a6e24fb6e6f4297c9e06820.zip |
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)))))
llvm-svn: 41483
-rw-r--r-- | clang/AST/ASTContext.cpp | 12 | ||||
-rw-r--r-- | clang/Sema/SemaExpr.cpp | 33 | ||||
-rw-r--r-- | clang/include/clang/AST/ASTContext.h | 7 |
3 files changed, 37 insertions, 15 deletions
diff --git a/clang/AST/ASTContext.cpp b/clang/AST/ASTContext.cpp index b0b963c4c80..4b79582e524 100644 --- a/clang/AST/ASTContext.cpp +++ b/clang/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/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index 9033ee917fc..6cabbda8e2e 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/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/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 431d298471b..2bfc6af89a3 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/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). |