r311880 - [StaticAnalyzer] LoopUnrolling fixes

Peter Szecsi via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 28 03:21:24 PDT 2017


Author: szepet
Date: Mon Aug 28 03:21:24 2017
New Revision: 311880

URL: http://llvm.org/viewvc/llvm-project?rev=311880&view=rev
Log:
[StaticAnalyzer] LoopUnrolling fixes

1. The LoopUnrolling feature needs the LoopExit included in the CFG so added this
dependency via the config options
2. The LoopExit element can be encountered even if we haven't encountered the 
block of the corresponding LoopStmt. So the asserts were not right.
3. If we are caching out the Node then we get a nullptr from generateNode which
case was not handled.


Differential Revision: https://reviews.llvm.org/D37103

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
    cfe/trunk/test/Analysis/loop-unrolling.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp?rev=311880&r1=311879&r2=311880&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp Mon Aug 28 03:21:24 2017
@@ -27,7 +27,9 @@ AnalysisManager::AnalysisManager(ASTCont
               /*AddInitializers=*/true,
               Options.includeTemporaryDtorsInCFG(),
 	            Options.includeLifetimeInCFG(),
-              Options.includeLoopExitInCFG(),
+              // Adding LoopExit elements to the CFG is a requirement for loop
+              // unrolling.
+              Options.includeLoopExitInCFG() || Options.shouldUnrollLoops(),
               Options.shouldSynthesizeBodies(),
               Options.shouldConditionalizeStaticInitializers(),
               /*addCXXNewAllocator=*/true,

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=311880&r1=311879&r2=311880&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Aug 28 03:21:24 2017
@@ -1527,8 +1527,11 @@ void ExprEngine::processCFGBlockEntrance
     if (Term) {
       ProgramStateRef NewState = updateLoopStack(Term, AMgr.getASTContext(),
                                                  Pred);
-      if (NewState != Pred->getState()){
-        Pred = nodeBuilder.generateNode(NewState, Pred);
+      if (NewState != Pred->getState()) {
+        ExplodedNode *UpdatedNode = nodeBuilder.generateNode(NewState, Pred);
+        if (!UpdatedNode)
+          return;
+        Pred = UpdatedNode;
       }
     }
     // Is we are inside an unrolled loop then no need the check the counters.

Modified: cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp?rev=311880&r1=311879&r2=311880&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp Mon Aug 28 03:21:24 2017
@@ -13,15 +13,11 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#include "clang/Analysis/CFGStmtMap.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/AST/ParentMap.h"
-#include "clang/AST/StmtVisitor.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h"
-#include "llvm/ADT/Statistic.h"
 
 using namespace clang;
 using namespace ento;
@@ -72,11 +68,8 @@ static bool isLoopStmt(const Stmt *S) {
 
 ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State) {
   auto LS = State->get<LoopStack>();
-  assert(!LS.isEmpty() && "Loop not added to the stack.");
-  assert(LoopStmt == LS.getHead().getLoopStmt() &&
-         "Loop is not on top of the stack.");
-
-  State = State->set<LoopStack>(LS.getTail());
+  if (!LS.isEmpty() && LS.getHead().getLoopStmt() == LoopStmt)
+    State = State->set<LoopStack>(LS.getTail());
   return State;
 }
 

Modified: cfe/trunk/test/Analysis/loop-unrolling.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/loop-unrolling.cpp?rev=311880&r1=311879&r2=311880&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/loop-unrolling.cpp (original)
+++ cfe/trunk/test/Analysis/loop-unrolling.cpp Mon Aug 28 03:21:24 2017
@@ -272,3 +272,10 @@ int recursion_unroll4(bool b) {
   int a = 22 / k;
   return 0;
 }
+
+int loop_exit_while_empty_loop_stack() {
+  if (getNum())
+    for (int i = 1; i < 8; i++)
+      ;
+  return 0;
+}




More information about the cfe-commits mailing list