summaryrefslogtreecommitdiff
path: root/test/SemaCXX
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-12-08 22:57:11 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-12-08 22:57:11 +0000
commit7bc2da619c0bba92606ef94d96921d7f4d83c925 (patch)
treeb2369c4d11c14c583192064940aed2b21ffdfa9d /test/SemaCXX
parent5e1ed772d8e34afe9be999cbc16c6252d0846bc4 (diff)
Unify implementation of our two different flavours of -Wtautological-compare,
and fold together into a single function. In so doing, fix a handful of remaining bugs where we would report false positives or false negatives if we promote a signed value to an unsigned type for the comparison. This re-commits r320122 and r320124, minus two changes: * Comparisons between a constant and a non-constant expression of enumeration type never warn, not even if the constant is out of range. We should be warning about the creation of such a constant, not about its use. * We do not use more precise bit-widths for comparisons against bit-fields. The more precise diagnostics probably are the right thing, but we should consider moving them under their own warning flag. Other than the refactoring, this patch should only change the behavior for the buggy cases (where the warnings didn't take into account that promotion from signed to unsigned can leave a range of inaccessible values in the middle of the promoted type). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@320211 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaCXX')
-rw-r--r--test/SemaCXX/compare.cpp20
1 files changed, 18 insertions, 2 deletions
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index 1d940be629..d852180c06 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -245,8 +245,8 @@ void test4(short s) {
// unsigned.
const unsigned B = -1;
void (s < B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
- void (s > B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
- void (s <= B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
+ void (s > B); // expected-warning{{comparison 'short' > 4294967295 is always false}}
+ void (s <= B); // expected-warning{{comparison 'short' <= 4294967295 is always true}}
void (s >= B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
void (s == B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
void (s != B); // expected-warning{{comparison of integers of different signs: 'short' and 'const unsigned int'}}
@@ -423,3 +423,19 @@ namespace templates {
testx<B>();
}
}
+
+namespace tautological_enum {
+ enum E { a, b, c } e;
+
+ // FIXME: We should warn about constructing this out-of-range numeration value.
+ const E invalid = (E)-1;
+ // ... but we should not warn about comparing against it.
+ bool x = e == invalid;
+
+ // We should not warn about relational comparisons for enumerators, even if
+ // they're tautological.
+ bool y = e >= a && e <= b;
+ const E first_in_range = a;
+ const E last_in_range = b;
+ bool z = e >= first_in_range && e <= last_in_range;
+}