]> granicus.if.org Git - clang/commitdiff
Provide a slightly specialized diagnostic for tautological comparisons
authorJohn McCall <rjmccall@apple.com>
Wed, 6 Oct 2010 00:25:24 +0000 (00:25 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 6 Oct 2010 00:25:24 +0000 (00:25 +0000)
of an enum value.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115725 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaChecking.cpp
test/Sema/compare.c

index 42b22f4f5542252c1d540eb1d1d1310aa5d11e2f..fafce83b9aa68e5d5dea576dfe90ea5dc1636566 100644 (file)
@@ -2251,10 +2251,10 @@ def warn_mixed_sign_conditional : Warning<
   "operands of ? are integers of different signs: %0 and %1">,
   InGroup<SignCompare>, DefaultIgnore;
 def warn_lunsigned_always_true_comparison : Warning<
-  "comparison of unsigned expression %0 is always %1">,
+  "comparison of unsigned%select{| enum}2 expression %0 is always %1">,
   InGroup<TautologicalCompare>;
 def warn_runsigned_always_true_comparison : Warning<
-  "comparison of %0 unsigned expression is always %1">,
+  "comparison of %0 unsigned%select{| enum}2 expression is always %1">,
   InGroup<TautologicalCompare>;
 
 def err_invalid_this_use : Error<
index e2cc2f32637e542822af1932f34f86ee192e4cc7..e79b639229626e46607d04f7408d4801f00dc50a 100644 (file)
@@ -2451,23 +2451,39 @@ static bool IsZero(Sema &S, Expr *E) {
   return E->isIntegerConstantExpr(Value, S.Context) && Value == 0;
 }
 
+static bool HasEnumType(Expr *E) {
+  // Strip off implicit integral promotions.
+  while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+    switch (ICE->getCastKind()) {
+    case CK_IntegralCast:
+    case CK_NoOp:
+      E = ICE->getSubExpr();
+      continue;
+    default:
+      break;
+    }
+  }
+
+  return E->getType()->isEnumeralType();
+}
+
 void CheckTrivialUnsignedComparison(Sema &S, BinaryOperator *E) {
   BinaryOperatorKind op = E->getOpcode();
   if (op == BO_LT && IsZero(S, E->getRHS())) {
     S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison)
-      << "< 0" << "false"
+      << "< 0" << "false" << HasEnumType(E->getLHS())
       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
   } else if (op == BO_GE && IsZero(S, E->getRHS())) {
     S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison)
-      << ">= 0" << "true"
+      << ">= 0" << "true" << HasEnumType(E->getLHS())
       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
   } else if (op == BO_GT && IsZero(S, E->getLHS())) {
     S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison)
-      << "0 >" << "false" 
+      << "0 >" << "false" << HasEnumType(E->getRHS())
       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
   } else if (op == BO_LE && IsZero(S, E->getLHS())) {
     S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison)
-      << "0 <=" << "true" 
+      << "0 <=" << "true" << HasEnumType(E->getRHS())
       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
   }
 }
index 2a6917e6079f8e7307d5425af839344b39f2a76b..5221b172a602720d0865f26af3da0f51b0c8a514 100644 (file)
@@ -305,3 +305,10 @@ int rdar8414119_bar(unsigned x) {
 #undef ZERO
 #undef CHECK
 
+int rdar8511238() {
+  enum A { A_foo, A_bar };
+  enum A a;
+  if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
+    return 0;
+  return 20;
+}