Classify (small unsigned bitfield) < 0 comparisons under
authorRichard Smith <richard@metafoo.co.uk>
Tue, 1 Sep 2020 06:12:06 +0000 (23:12 -0700)
committerRichard Smith <richard@metafoo.co.uk>
Tue, 1 Sep 2020 06:16:48 +0000 (23:16 -0700)
-Wtautological-unsigned-zero-compare not under
-Wtautological-value-range-compare.

clang/lib/Sema/SemaChecking.cpp
clang/test/Sema/compare.c

index 3a2f070..2e07c8f 100644 (file)
@@ -10944,6 +10944,12 @@ static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E,
   if (InRange && IsEnumConstOrFromMacro(S, Constant))
     return false;
 
+  // A comparison of an unsigned bit-field against 0 is really a type problem,
+  // even though at the type level the bit-field might promote to 'signed int'.
+  if (Other->refersToBitField() && InRange && Value == 0 &&
+      Other->getType()->isUnsignedIntegerOrEnumerationType())
+    TautologicalTypeCompare = true;
+
   // If this is a comparison to an enum constant, include that
   // constant in the diagnostic.
   const EnumConstantDecl *ED = nullptr;
index 25aa13f..85dcffc 100644 (file)
@@ -285,6 +285,20 @@ int test5(unsigned int x) {
     && (0 <= x); // expected-warning {{comparison of 0 <= unsigned expression is always true}}
 }
 
+struct bitfield {
+  int a : 3;
+  unsigned b : 3;
+  long c : 40;
+  unsigned long d : 40;
+};
+
+void test5a(struct bitfield a) {
+  if (a.a < 0) {}
+  if (a.b < 0) {} // expected-warning {{comparison of unsigned expression < 0 is always false}}
+  if (a.c < 0) {}
+  if (a.d < 0) {} // expected-warning {{comparison of unsigned expression < 0 is always false}}
+}
+
 int test6(unsigned i, unsigned power) {
   unsigned x = (i < (1 << power) ? i : 0);
   return x != 3 ? 1 << power : i;