aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-07-13 06:35:24 +0000
committerJohn McCall <rjmccall@apple.com>2011-07-13 06:35:24 +0000
commit862ff87c0d306af8dfdbe7ac59f181a5815546e5 (patch)
treed6e05c1182672cf61bfd18beff13d946025b30c4
parentc3c0766277cd64bf117450a1519c9cf762d994d4 (diff)
Make the integer-range analysis recognize ^= correctly,
and (while I'm at it) teach it to grok the results of simple assignments. The first is PR10336. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135034 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaChecking.cpp13
-rw-r--r--test/Sema/compare.c15
2 files changed, 26 insertions, 2 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 8bad032911..267cda8f40 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -2586,15 +2586,24 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
case BO_NE:
return IntRange::forBoolType();
- // The type of these compound assignments is the type of the LHS,
- // so the RHS is not necessarily an integer.
+ // The type of the assignments is the type of the LHS, so the RHS
+ // is not necessarily the same type.
case BO_MulAssign:
case BO_DivAssign:
case BO_RemAssign:
case BO_AddAssign:
case BO_SubAssign:
+ case BO_XorAssign:
+ case BO_OrAssign:
+ // TODO: bitfields?
return IntRange::forValueOfType(C, E->getType());
+ // Simple assignments just pass through the RHS, which will have
+ // been coerced to the LHS type.
+ case BO_Assign:
+ // TODO: bitfields?
+ return GetExprRange(C, BO->getRHS(), MaxWidth);
+
// Operations with opaque sources are black-listed.
case BO_PtrMemD:
case BO_PtrMemI:
diff --git a/test/Sema/compare.c b/test/Sema/compare.c
index 5221b172a6..cd973d4885 100644
--- a/test/Sema/compare.c
+++ b/test/Sema/compare.c
@@ -312,3 +312,18 @@ int rdar8511238() {
return 0;
return 20;
}
+
+// PR10336
+int test9(int sv, unsigned uv, long slv) {
+ return sv == (uv ^= slv); // expected-warning {{comparison of integers of different signs: 'int' and 'unsigned int'}}
+}
+
+void test10(void) {
+ int si;
+ unsigned int ui;
+ long sl;
+
+ _Bool b;
+ b = (si == (ui = sl)); // expected-warning {{comparison of integers of different signs: 'int' and 'unsigned int'}}
+ b = (si == (ui = sl&15));
+}