aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/BugReporter.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2013-05-04 01:13:08 +0000
committerTed Kremenek <kremenek@apple.com>2013-05-04 01:13:08 +0000
commitf468fa16e37fc8fa6a915fe36aee8f0434709789 (patch)
tree730a0db0ffab4f795a8fb02201f8fd6da3856836 /lib/StaticAnalyzer/Core/BugReporter.cpp
parentb9e13d555fc9f3e5515e2b1fa6f720e6f10bb076 (diff)
[analyzer; alternate edges] - eliminate unnecessary edges where between parents and subexpressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181086 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/BugReporter.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp76
1 files changed, 68 insertions, 8 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 827bf09b05..759503a688 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -1738,10 +1738,13 @@ GenerateAlternateExtensivePathDiagnostic(PathDiagnostic& PD,
return report->isValid();
}
-const Stmt *getLocParent(PathDiagnosticLocation L, ParentMap &PM) {
+const Stmt *getLocStmt(PathDiagnosticLocation L) {
if (!L.isValid())
return 0;
- const Stmt *S = L.asStmt();
+ return L.asStmt();
+}
+
+const Stmt *getStmtParent(const Stmt *S, ParentMap &PM) {
if (!S)
return 0;
return PM.getParent(S);
@@ -1752,6 +1755,7 @@ static bool optimizeEdges(PathPieces &path,
bool hasChanges = false;
const LocationContext *LC = LCM[&path];
assert(LC);
+ bool isFirst = true;
for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ++I) {
PathPieces::iterator NextI = I; ++NextI;
@@ -1771,13 +1775,34 @@ static bool optimizeEdges(PathPieces &path,
if (!PieceI)
continue;
+ ParentMap &PM = LC->getParentMap();
+ const Stmt *s1Start = getLocStmt(PieceI->getStartLocation());
+ const Stmt *s1End = getLocStmt(PieceI->getEndLocation());
+ const Stmt *level1 = getStmtParent(s1Start, PM);
+ const Stmt *level2 = getStmtParent(s1End, PM);
+
+ if (isFirst) {
+ isFirst = false;
+ // Apply the "first edge" case for Rule III. here.
+ if (level1 && level2 && level2 == PM.getParent(level1)) {
+ path.erase(I);
+ // Since we are erasing the current edge at the start of the
+ // path, just return now so we start analyzing the start of the path
+ // again.
+ return true;
+ }
+ }
+
PathDiagnosticControlFlowPiece *PieceNextI =
dyn_cast<PathDiagnosticControlFlowPiece>(*NextI);
if (!PieceNextI)
continue;
- ParentMap &PM = LC->getParentMap();
+ const Stmt *s2Start = getLocStmt(PieceNextI->getStartLocation());
+ const Stmt *s2End = getLocStmt(PieceNextI->getEndLocation());
+ const Stmt *level3 = getStmtParent(s2Start, PM);
+ const Stmt *level4 = getStmtParent(s2End, PM);
// Rule I.
//
@@ -1791,11 +1816,7 @@ static bool optimizeEdges(PathPieces &path,
//
// NOTE: this will be limited later in cases where we add barriers
// to prevent this optimization.
- const Stmt *level1 = getLocParent(PieceI->getStartLocation(), PM);
- const Stmt *level2 = getLocParent(PieceI->getEndLocation(), PM);
- const Stmt *level3 = getLocParent(PieceNextI->getStartLocation(), PM);
- const Stmt *level4 = getLocParent(PieceNextI->getEndLocation(), PM);
-
+ //
if (level1 && level1 == level2 && level1 == level3 && level1 == level4) {
PieceI->setEndLocation(PieceNextI->getEndLocation());
path.erase(NextI);
@@ -1822,6 +1843,45 @@ static bool optimizeEdges(PathPieces &path,
hasChanges = true;
continue;
}
+
+ // Rule III.
+ //
+ // Eliminate unnecessary edges where we descend to a subexpression from
+ // a statement at the same level as our parent.
+ //
+ // NOTE: this will be limited later in cases where we add barriers
+ // to prevent this optimization.
+ //
+ // For example:
+ //
+ // (1.1 -> 1.1.1) -> (1.1.1 -> X) becomes (1.1 -> X).
+ //
+ if (level1 && level2 && level1 == PM.getParent(level2)) {
+ PieceI->setEndLocation(PieceNextI->getEndLocation());
+ path.erase(NextI);
+ hasChanges = true;
+ continue;
+ }
+
+ // Rule IV.
+ //
+ // Eliminate unnecessary edges where we ascend from a subexpression to
+ // a statement at the same level as our parent.
+ //
+ // NOTE: this will be limited later in cases where we add barriers
+ // to prevent this optimization.
+ //
+ // For example:
+ //
+ // (X -> 1.1.1) -> (1.1.1 -> 1.1) becomes (X -> 1.1).
+ // [first edge] (1.1.1 -> 1.1) -> eliminate
+ //
+ if (level2 && level4 && level2 == level3 && level4 == PM.getParent(level2)){
+ PieceI->setEndLocation(PieceNextI->getEndLocation());
+ path.erase(NextI);
+ hasChanges = true;
+ continue;
+ }
}
// No changes.