summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2007-08-27 15:30:22 +0000
committerSteve Naroff <snaroff@apple.com>2007-08-27 15:30:22 +0000
commit7af82d462ac2d1960a6e24fb6e6f4297c9e06820 (patch)
tree93a2521d00e673c650ddb7954980e116e072be30
parent032d89828e148b846e90e5ba498779adf26d8958 (diff)
downloadbcm5719-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.cpp12
-rw-r--r--clang/Sema/SemaExpr.cpp33
-rw-r--r--clang/include/clang/AST/ASTContext.h7
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).
OpenPOWER on IntegriCloud