]> granicus.if.org Git - clang/commitdiff
Eliminate some false positives due to a thinko in the "'blah' is
authorDouglas Gregor <dgregor@apple.com>
Thu, 5 Nov 2009 17:49:26 +0000 (17:49 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 5 Nov 2009 17:49:26 +0000 (17:49 +0000)
always zero in this context" warning logic. Also, make the diagnostic
itself more precise when referring to pointer values ("NULL" vs. "zero").

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

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Parse/Scope.h
lib/Sema/SemaExpr.cpp
test/SemaCXX/warn-for-var-in-else.cpp

index 2309908df7b4e580602d12d742938692aa41060d..06b09a0b7304f72382bc55834be70bf143af4f2d 100644 (file)
@@ -1787,8 +1787,8 @@ def warn_condition_is_assignment : Warning<"using the result of an "
   "assignment as a condition without parentheses">,
   InGroup<Parentheses>;
 
-def warn_value_always_zero : Warning<"%0 is always zero in this context">;
-def warn_value_always_false : Warning<"%0 is always false in this context">;
+def warn_value_always_zero : Warning<
+  "%0 is always %select{zero|false|NULL}1 in this context">;
 
 // assignment related diagnostics (also for argument passing, returning, etc).
 // FIXME: %2 is an english string here.
index 480b94f73f6218f813870b3482b7faa5e5129a1d..c6a1e53472c119990178329b23cb735b1f26f541 100644 (file)
@@ -275,7 +275,8 @@ public:
     AnyParent = Parent;
     Depth = AnyParent ? AnyParent->Depth+1 : 0;
     Flags = ScopeFlags;
-
+    WithinElse = false;
+    
     if (AnyParent) {
       FnParent       = AnyParent->FnParent;
       BreakParent    = AnyParent->BreakParent;
@@ -283,13 +284,10 @@ public:
       ControlParent = AnyParent->ControlParent;
       BlockParent  = AnyParent->BlockParent;
       TemplateParamParent = AnyParent->TemplateParamParent;
-      WithinElse = AnyParent->WithinElse;
-
     } else {
       FnParent = BreakParent = ContinueParent = BlockParent = 0;
       ControlParent = 0;
       TemplateParamParent = 0;
-      WithinElse = false;
     }
 
     // If this scope is a function or contains breaks/continues, remember it.
index f1d6f2bb17ce4b8b18971a1fee77b5c35d128bf7..f94017129b026041e0011742e7215cdedabd7f2d 100644 (file)
@@ -814,22 +814,18 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
     // information to check this property.
     if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
       Scope *CheckS = S;
-      while (CheckS) {
+      while (CheckS && CheckS->getControlParent()) {
         if (CheckS->isWithinElse() &&
             CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
-          if (Var->getType()->isBooleanType())
-            ExprError(Diag(Loc, diag::warn_value_always_false)
-                      << Var->getDeclName());
-          else
-            ExprError(Diag(Loc, diag::warn_value_always_zero)
-                      << Var->getDeclName());
+          ExprError(Diag(Loc, diag::warn_value_always_zero)
+            << Var->getDeclName()
+            << (Var->getType()->isPointerType()? 2 :
+                Var->getType()->isBooleanType()? 1 : 0));
           break;
         }
 
-        // Move up one more control parent to check again.
-        CheckS = CheckS->getControlParent();
-        if (CheckS)
-          CheckS = CheckS->getParent();
+        // Move to the parent of this scope.
+        CheckS = CheckS->getParent();
       }
     }
   } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) {
index f73c60689446c62f971b38836d4845542be7590a..c46b30640fb2b9e4972749e5705f4cc82b4dce7a 100644 (file)
@@ -2,6 +2,7 @@
 // rdar://6425550
 int bar();
 void do_something(int);
+int *get_ptr();
 
 int foo() {
   if (int X = bar()) {
@@ -25,7 +26,20 @@ bool foo2() {
       do_something(B); // expected-warning{{'B' is always false in this context}}
     } else if (B2) {  // expected-warning{{'B2' is always false in this context}}
       do_something(B); // expected-warning{{'B' is always false in this context}}
+      do_something(B2); // expected-warning{{'B2' is always false in this context}}
     }
     return B; // expected-warning{{'B' is always false in this context}}
   }
 }
+
+void foo3() {  
+  if (int *P1 = get_ptr())
+    do_something(*P1);
+  else if (int *P2 = get_ptr()) {
+    do_something(*P1); // expected-warning{{'P1' is always NULL in this context}}
+    do_something(*P2);
+  } else {
+    do_something(*P1); // expected-warning{{'P1' is always NULL in this context}}
+    do_something(*P2); // expected-warning{{'P2' is always NULL in this context}}
+  }
+}