r182426 - [analyzer; alternate edges] prune out extra edges to a subexpression where we dive-in and out of a subexpression.
Ted Kremenek
kremenek at apple.com
Tue May 21 14:38:05 PDT 2013
Author: kremenek
Date: Tue May 21 16:38:05 2013
New Revision: 182426
URL: http://llvm.org/viewvc/llvm-project?rev=182426&view=rev
Log:
[analyzer;alternate edges] prune out extra edges to a subexpression where we dive-in and out of a subexpression.
Fixes <rdar://problem/13941891>.
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=182426&r1=182425&r2=182426&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Tue May 21 16:38:05 2013
@@ -1950,6 +1950,18 @@ void PathPieces::dump() const {
}
}
+/// \brief Return true if X is contained by Y.
+static bool lexicalContains(ParentMap &PM,
+ const Stmt *X,
+ const Stmt *Y) {
+ while (X) {
+ if (X == Y)
+ return true;
+ X = PM.getParent(X);
+ }
+ return false;
+}
+
static bool optimizeEdges(PathPieces &path, SourceManager &SM,
OptimizedCallsSet &OCS,
LocationContextMap &LCM) {
@@ -2058,10 +2070,40 @@ static bool optimizeEdges(PathPieces &pa
// to prevent this optimization.
//
if (s1End && s1End == s2Start && level2) {
- if (isIncrementOrInitInForLoop(s1End, level2) ||
- (isa<Expr>(s1End) && PM.isConsumedExpr(cast<Expr>(s1End)) &&
- !isConditionForTerminator(level2, s1End)))
- {
+ bool removeEdge = false;
+ // Remove edges into the increment or initialization of a
+ // loop that have no interleaving event. This means that
+ // they aren't interesting.
+ if (isIncrementOrInitInForLoop(s1End, level2))
+ removeEdge = true;
+ // Next only consider edges that are not anchored on
+ // the condition of a terminator. This are intermediate edges
+ // that we might want to trim.
+ else if (!isConditionForTerminator(level2, s1End)) {
+ // Trim edges on expressions that are consumed by
+ // the parent expression.
+ if (isa<Expr>(s1End) && PM.isConsumedExpr(cast<Expr>(s1End))) {
+ removeEdge = true;
+ }
+ // Trim edges where a lexical containment doesn't exist.
+ // For example:
+ //
+ // X -> Y -> Z
+ //
+ // If 'Z' lexically contains Y (it is an ancestor) and
+ // 'X' does not lexically contain Y (it is a descendant OR
+ // it has no lexical relationship at all) then trim.
+ //
+ // This can eliminate edges where we dive into a subexpression
+ // and then pop back out, etc.
+ else if (s1Start && s2End &&
+ lexicalContains(PM, s2Start, s2End) &&
+ !lexicalContains(PM, s1End, s1Start)) {
+ removeEdge = true;
+ }
+ }
+
+ if (removeEdge) {
PieceI->setEndLocation(PieceNextI->getEndLocation());
path.erase(NextI);
hasChanges = true;
More information about the cfe-commits
mailing list