]> granicus.if.org Git - clang/commitdiff
[-Wunreachable-code] Expand paren-suppression heuristic to C++/ObjC bools.
authorTed Kremenek <kremenek@apple.com>
Sat, 29 Mar 2014 04:49:20 +0000 (04:49 +0000)
committerTed Kremenek <kremenek@apple.com>
Sat, 29 Mar 2014 04:49:20 +0000 (04:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205074 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ReachableCode.cpp
test/SemaCXX/warn-unreachable.cpp
test/SemaObjC/warn-unreachable.m

index 7c8ea39dc56f61219cc7b93ce0fd6ed622c0d6d2..3cc8ae4a08109fb07c90b75c845c5a23750cf6b1 100644 (file)
@@ -141,12 +141,15 @@ static bool isConfigurationValue(const Stmt *S,
 
   // Special case looking for the sigil '()' around an integer literal.
   if (const ParenExpr *PE = dyn_cast<ParenExpr>(S))
-    return isConfigurationValue(PE->getSubExpr(), PP, SilenceableCondVal, 
-                                IncludeIntegers, true);
+    if (!PE->getLocStart().isMacroID())
+      return isConfigurationValue(PE->getSubExpr(), PP, SilenceableCondVal, 
+                                  IncludeIntegers, true);
 
   if (const Expr *Ex = dyn_cast<Expr>(S))
     S = Ex->IgnoreParenCasts();
 
+  bool IgnoreYES_NO = false;
+
   switch (S->getStmtClass()) {
     case Stmt::CallExprClass: {
       const FunctionDecl *Callee =
@@ -155,19 +158,21 @@ static bool isConfigurationValue(const Stmt *S,
     }
     case Stmt::DeclRefExprClass:
       return isConfigurationValue(cast<DeclRefExpr>(S)->getDecl(), PP);
+    case Stmt::ObjCBoolLiteralExprClass:
+      IgnoreYES_NO = true;
+      // Fallthrough.
+    case Stmt::CXXBoolLiteralExprClass:
     case Stmt::IntegerLiteralClass: {
-      const IntegerLiteral *E = cast<IntegerLiteral>(S);
+      const Expr *E = cast<Expr>(S);
       if (IncludeIntegers) {
         if (SilenceableCondVal && !SilenceableCondVal->getBegin().isValid())
           *SilenceableCondVal = E->getSourceRange();
-        return WrappedInParens || isExpandedFromConfigurationMacro(E, PP);
+        return WrappedInParens || isExpandedFromConfigurationMacro(E, PP, IgnoreYES_NO);
       }
       return false;
     }
     case Stmt::MemberExprClass:
       return isConfigurationValue(cast<MemberExpr>(S)->getMemberDecl(), PP);
-    case Stmt::ObjCBoolLiteralExprClass:
-      return isExpandedFromConfigurationMacro(S, PP, /* IgnoreYES_NO */ true);
     case Stmt::UnaryExprOrTypeTraitExprClass:
       return true;
     case Stmt::BinaryOperatorClass: {
index 8acaf428551808b28916469af86e96ffc3ef726f..04bd74304b7343ac077deae0ea90f23e171f1463 100644 (file)
@@ -294,3 +294,36 @@ void test_unreachable_forrange_increment() {
   }
 }
 
+void calledFun() {}
+
+// Test "silencing" with parentheses.
+void test_with_paren_silencing(int x) {
+  if (false) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+  if ((false)) calledFun(); // no-warning
+
+  if (true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun();
+  else
+    calledFun(); // expected-warning {{will never be executed}}
+
+  if ((true))
+    calledFun();
+  else
+    calledFun(); // no-warning
+  
+  if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun(); // expected-warning {{code will never be executed}}
+  else
+    calledFun();
+  
+  if ((!true))
+    calledFun(); // no-warning
+  else
+    calledFun();
+  
+  if (!(true))
+    calledFun(); // no-warning
+  else
+    calledFun();
+}
+
index 859bd00f310b12db504897c0e3f613b45e028f0b..366767629d2da678d02f9c1247fffa50fd9aa907 100644 (file)
@@ -49,3 +49,36 @@ void test_loop_increment(id container) {
   }
 }
 
+void calledFun() {}
+
+// Test "silencing" with parentheses.
+void test_with_paren_silencing(int x) {
+  if (NO) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+  if ((NO)) calledFun(); // no-warning
+
+  if (YES) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun();
+  else
+    calledFun(); // expected-warning {{will never be executed}}
+
+  if ((YES))
+    calledFun();
+  else
+    calledFun(); // no-warning
+  
+  if (!YES) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun(); // expected-warning {{code will never be executed}}
+  else
+    calledFun();
+  
+  if ((!YES))
+    calledFun(); // no-warning
+  else
+    calledFun();
+  
+  if (!(YES))
+    calledFun(); // no-warning
+  else
+    calledFun();
+}
+