45
45
#include " ClangSACheckers.h"
46
46
#include " clang/Analysis/CFGStmtMap.h"
47
47
#include " clang/Analysis/Analyses/PseudoConstantAnalysis.h"
48
+ #include " clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
48
49
#include " clang/StaticAnalyzer/Core/CheckerManager.h"
49
50
#include " clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
50
51
#include " clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -83,9 +84,8 @@ class IdempotentOperationChecker
83
84
static bool isUnused (const Expr *E, AnalysisContext *AC);
84
85
static bool isTruncationExtensionAssignment (const Expr *LHS,
85
86
const Expr *RHS);
86
- bool pathWasCompletelyAnalyzed (const CFG *cfg ,
87
+ bool pathWasCompletelyAnalyzed (AnalysisContext *AC ,
87
88
const CFGBlock *CB,
88
- const CFGStmtMap *CBM,
89
89
const CoreEngine &CE);
90
90
static bool CanVary (const Expr *Ex,
91
91
AnalysisContext *AC);
@@ -105,26 +105,6 @@ class IdempotentOperationChecker
105
105
typedef llvm::DenseMap<const BinaryOperator *, BinaryOperatorData>
106
106
AssumptionMap;
107
107
AssumptionMap hash;
108
-
109
- // A class that performs reachability queries for CFGBlocks. Several internal
110
- // checks in this checker require reachability information. The requests all
111
- // tend to have a common destination, so we lazily do a predecessor search
112
- // from the destination node and cache the results to prevent work
113
- // duplication.
114
- class CFGReachabilityAnalysis {
115
- typedef llvm::BitVector ReachableSet;
116
- typedef llvm::DenseMap<unsigned , ReachableSet> ReachableMap;
117
- ReachableSet analyzed;
118
- ReachableMap reachable;
119
- public:
120
- CFGReachabilityAnalysis (const CFG &cfg)
121
- : analyzed(cfg.getNumBlockIDs(), false ) {}
122
-
123
- inline bool isReachable (const CFGBlock *Src, const CFGBlock *Dst);
124
- private:
125
- void MapReachability (const CFGBlock *Dst);
126
- };
127
- llvm::OwningPtr<CFGReachabilityAnalysis> CRA;
128
108
};
129
109
}
130
110
@@ -397,11 +377,9 @@ void IdempotentOperationChecker::VisitEndAnalysis(ExplodedGraph &G,
397
377
// If the analyzer did not finish, check to see if we can still emit this
398
378
// warning
399
379
if (Eng.hasWorkRemaining ()) {
400
- const CFGStmtMap *CBM = AC->getCFGStmtMap ();
401
-
402
380
// If we can trace back
403
- if (!pathWasCompletelyAnalyzed (AC-> getCFG () ,
404
- CBM-> getBlock (B), CBM ,
381
+ if (!pathWasCompletelyAnalyzed (AC,
382
+ AC-> getCFGStmtMap ()-> getBlock (B),
405
383
Eng.getCoreEngine ()))
406
384
continue ;
407
385
}
@@ -561,13 +539,11 @@ bool IdempotentOperationChecker::isTruncationExtensionAssignment(
561
539
// Returns false if a path to this block was not completely analyzed, or true
562
540
// otherwise.
563
541
bool
564
- IdempotentOperationChecker::pathWasCompletelyAnalyzed (const CFG *cfg ,
542
+ IdempotentOperationChecker::pathWasCompletelyAnalyzed (AnalysisContext *AC ,
565
543
const CFGBlock *CB,
566
- const CFGStmtMap *CBM,
567
544
const CoreEngine &CE) {
568
545
569
- if (!CRA.get ())
570
- CRA.reset (new CFGReachabilityAnalysis (*cfg));
546
+ CFGReachabilityAnalysis *CRA = AC->getCFGReachablityAnalysis ();
571
547
572
548
// Test for reachability from any aborted blocks to this block
573
549
typedef CoreEngine::BlocksAborted::const_iterator AbortedIterator;
@@ -618,14 +594,14 @@ IdempotentOperationChecker::pathWasCompletelyAnalyzed(const CFG *cfg,
618
594
return CRA.isReachable (B, TargetBlock);
619
595
}
620
596
};
621
- VisitWL visitWL (CBM , CB, *CRA. get () );
597
+ VisitWL visitWL (AC-> getCFGStmtMap () , CB, *CRA);
622
598
// Were there any items in the worklist that could potentially reach
623
599
// this block?
624
600
if (CE.getWorkList ()->visitItemsInWorkList (visitWL))
625
601
return false ;
626
602
627
603
// Verify that this block is reachable from the entry block
628
- if (!CRA->isReachable (&cfg ->getEntry (), CB))
604
+ if (!CRA->isReachable (&AC-> getCFG () ->getEntry (), CB))
629
605
return false ;
630
606
631
607
// If we get to this point, there is no connection to the entry block or an
@@ -763,57 +739,6 @@ bool IdempotentOperationChecker::containsNonLocalVarDecl(const Stmt *S) {
763
739
return false ;
764
740
}
765
741
766
- bool IdempotentOperationChecker::CFGReachabilityAnalysis::isReachable (
767
- const CFGBlock *Src,
768
- const CFGBlock *Dst) {
769
- const unsigned DstBlockID = Dst->getBlockID ();
770
-
771
- // If we haven't analyzed the destination node, run the analysis now
772
- if (!analyzed[DstBlockID]) {
773
- MapReachability (Dst);
774
- analyzed[DstBlockID] = true ;
775
- }
776
-
777
- // Return the cached result
778
- return reachable[DstBlockID][Src->getBlockID ()];
779
- }
780
742
781
- // Maps reachability to a common node by walking the predecessors of the
782
- // destination node.
783
- void IdempotentOperationChecker::CFGReachabilityAnalysis::MapReachability (
784
- const CFGBlock *Dst) {
785
743
786
- llvm::SmallVector<const CFGBlock *, 11 > worklist;
787
- llvm::BitVector visited (analyzed.size ());
788
-
789
- ReachableSet &DstReachability = reachable[Dst->getBlockID ()];
790
- DstReachability.resize (analyzed.size (), false );
791
-
792
- // Start searching from the destination node, since we commonly will perform
793
- // multiple queries relating to a destination node.
794
- worklist.push_back (Dst);
795
- bool firstRun = true ;
796
-
797
- while (!worklist.empty ()) {
798
- const CFGBlock *block = worklist.back ();
799
- worklist.pop_back ();
800
-
801
- if (visited[block->getBlockID ()])
802
- continue ;
803
- visited[block->getBlockID ()] = true ;
804
-
805
- // Update reachability information for this node -> Dst
806
- if (!firstRun) {
807
- // Don't insert Dst -> Dst unless it was a predecessor of itself
808
- DstReachability[block->getBlockID ()] = true ;
809
- }
810
- else
811
- firstRun = false ;
812
744
813
- // Add the predecessors to the worklist.
814
- for (CFGBlock::const_pred_iterator i = block->pred_begin (),
815
- e = block->pred_end (); i != e; ++i) {
816
- worklist.push_back (*i);
817
- }
818
- }
819
- }
0 commit comments