diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2008-06-28 06:23:08 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2008-06-28 06:23:08 +0000 |
commit | 4f89ccb1dfc8cd1b21db5571308bfda676068090 (patch) | |
tree | 6a0b3ec39d175ab2b0fd4ac29293382e4b23fbd2 /clang/lib/Sema | |
parent | 853fbea313b8be8cbfd2ac94e3e366300621aad6 (diff) | |
download | bcm5719-llvm-4f89ccb1dfc8cd1b21db5571308bfda676068090.tar.gz bcm5719-llvm-4f89ccb1dfc8cd1b21db5571308bfda676068090.zip |
Fix for PR2501; this patch makes usual arithmetic conversions for
integers which have the same width and different signedness work
correctly. (The testcase in PR2501 uses a comparison between long and
unsigned int).
llvm-svn: 52853
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 97513925fda..8ef94864590 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1221,12 +1221,35 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, } } // Finally, we have two differing integer types. - if (Context.getIntegerTypeOrder(lhs, rhs) >= 0) { // convert the rhs - if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs); - return lhs; + // The rules for this case are in C99 6.3.1.8 + int compare = Context.getIntegerTypeOrder(lhs, rhs); + bool lhsSigned = lhs->isSignedIntegerType(), + rhsSigned = rhs->isSignedIntegerType(); + QualType destType; + if (lhsSigned == rhsSigned) { + // Same signedness; use the higher-ranked type + destType = compare >= 0 ? lhs : rhs; + } else if (compare != (lhsSigned ? 1 : -1)) { + // The unsigned type has greater than or equal rank to the + // signed type, so use the unsigned type + destType = lhsSigned ? rhs : lhs; + } else if (Context.getIntWidth(lhs) != Context.getIntWidth(rhs)) { + // The two types are different widths; if we are here, that + // means the signed type is larger than the unsigned type, so + // use the signed type. + destType = lhsSigned ? lhs : rhs; + } else { + // The signed type is higher-ranked than the unsigned type, + // but isn't actually any bigger (like unsigned int and long + // on most 32-bit systems). Use the unsigned type corresponding + // to the signed type. + destType = Context.getCorrespondingUnsignedType(lhsSigned ? lhs : rhs); + } + if (!isCompAssign) { + ImpCastExprToType(lhsExpr, destType); + ImpCastExprToType(rhsExpr, destType); } - if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs); // convert the lhs - return rhs; + return destType; } // CheckPointerTypesForAssignment - This is a very tricky routine (despite |