[cfe-commits] r154040 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp test/Analysis/dead-stores.c

Ted Kremenek kremenek at apple.com
Wed Apr 4 12:58:03 PDT 2012


Author: kremenek
Date: Wed Apr  4 14:58:03 2012
New Revision: 154040

URL: http://llvm.org/viewvc/llvm-project?rev=154040&view=rev
Log:
Look through chains of 'x = y = z' when employing silencing heuristics in the DeadStoresChecker.

Fixes <rdar://problem/11185138>.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
    cfe/trunk/test/Analysis/dead-stores.c

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp?rev=154040&r1=154039&r2=154040&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp Wed Apr  4 14:58:03 2012
@@ -68,6 +68,21 @@
   }
 }
 
+static const Expr *LookThroughTransitiveAssignments(const Expr *Ex) {
+  while (Ex) {
+    const BinaryOperator *BO =
+      dyn_cast<BinaryOperator>(Ex->IgnoreParenCasts());
+    if (!BO)
+      break;
+    if (BO->getOpcode() == BO_Assign) {
+      Ex = BO->getRHS();
+      continue;
+    }
+    break;
+  }
+  return Ex;
+}
+
 namespace {
 class DeadStoreObs : public LiveVariables::Observer {
   const CFG &cfg;
@@ -200,17 +215,18 @@
         if (VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
           // Special case: check for assigning null to a pointer.
           //  This is a common form of defensive programming.
+          const Expr *RHS = LookThroughTransitiveAssignments(B->getRHS());
+          
           QualType T = VD->getType();
           if (T->isPointerType() || T->isObjCObjectPointerType()) {
-            if (B->getRHS()->isNullPointerConstant(Ctx,
-                                              Expr::NPC_ValueDependentIsNull))
+            if (RHS->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNull))
               return;
           }
 
-          Expr *RHS = B->getRHS()->IgnoreParenCasts();
+          RHS = RHS->IgnoreParenCasts();
           // Special case: self-assignments.  These are often used to shut up
           //  "unused variable" compiler warnings.
-          if (DeclRefExpr *RhsDR = dyn_cast<DeclRefExpr>(RHS))
+          if (const DeclRefExpr *RhsDR = dyn_cast<DeclRefExpr>(RHS))
             if (VD == dyn_cast<VarDecl>(RhsDR->getDecl()))
               return;
 
@@ -252,10 +268,15 @@
           if (V->getType()->getAs<ReferenceType>())
             return;
             
-          if (Expr *E = V->getInit()) {
-            while (ExprWithCleanups *exprClean = dyn_cast<ExprWithCleanups>(E))
+          if (const Expr *E = V->getInit()) {
+            while (const ExprWithCleanups *exprClean =
+                    dyn_cast<ExprWithCleanups>(E))
               E = exprClean->getSubExpr();
             
+            // Look through transitive assignments, e.g.:
+            // int x = y = 0;
+            E = LookThroughTransitiveAssignments(E);
+            
             // Don't warn on C++ objects (yet) until we can show that their
             // constructors/destructors don't have side effects.
             if (isa<CXXConstructExpr>(E))
@@ -275,8 +296,9 @@
               if (E->isEvaluatable(Ctx))
                 return;
 
-              if (DeclRefExpr *DRE=dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
-                if (VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
+              if (const DeclRefExpr *DRE =
+                  dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
+                if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
                   // Special case: check for initialization from constant
                   //  variables.
                   //

Modified: cfe/trunk/test/Analysis/dead-stores.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dead-stores.c?rev=154040&r1=154039&r2=154040&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dead-stores.c (original)
+++ cfe/trunk/test/Analysis/dead-stores.c Wed Apr  4 14:58:03 2012
@@ -526,3 +526,25 @@
     rdar8405222_aux(i);
 }
 
+// Look through chains of assignements, e.g.: int x = y = 0, when employing
+// silencing heuristics.
+int radar11185138_foo() {
+  int x, y;
+  x = y = 0; // expected-warning {{never read}}
+  return y;
+}
+
+int rdar11185138_bar() {
+  int y;
+  int x = y = 0; // no-warning
+  x = 2;
+  y = 2;
+  return x + y;
+}
+
+int *radar11185138_baz() {
+  int *x, *y;
+  x = y = 0; // no-warning
+  return y;
+}
+





More information about the cfe-commits mailing list