summaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-11-01 01:05:39 +0000
committerJordan Rose <jordan_rose@apple.com>2012-11-01 01:05:39 +0000
commita4a9b3691d62d63285e8be4e6832e1a7221ffa31 (patch)
treef155341a44217b7f356196eab657e4d630c5a2f0 /clang
parent490bccd6596c496e9307fbc8639794f7fa2c165f (diff)
downloadllvm-a4a9b3691d62d63285e8be4e6832e1a7221ffa31.tar.gz
[analyzer] Optimize assumeDual by assuming constraint managers are consistent.
Specifically, if adding a constraint makes the current system infeasible, assume the constraint is false, instead of attempting to add its negation. In +Asserts builds we will still assert that at least one state is feasible. Patch by Ryan Govostes! llvm-svn: 167195
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h30
1 files changed, 24 insertions, 6 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index 6f1e70bdfd5a..34779e875c0d 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -69,12 +69,30 @@ public:
bool Assumption) = 0;
typedef std::pair<ProgramStateRef, ProgramStateRef> ProgramStatePair;
-
- ProgramStatePair assumeDual(ProgramStateRef state, DefinedSVal Cond) {
- ProgramStatePair res(assume(state, Cond, true),
- assume(state, Cond, false));
- assert(!(!res.first && !res.second) && "System is over constrained.");
- return res;
+
+ /// Returns a pair of states (StTrue, StFalse) where the given condition is
+ /// assumed to be true or false, respectively.
+ ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond) {
+ ProgramStateRef StTrue = assume(State, Cond, true);
+
+ // If StTrue is infeasible, asserting the falseness of Cond is unnecessary
+ // because the existing constraints already establish this.
+ if (!StTrue) {
+ // FIXME: This is fairly expensive and should be disabled even in
+ // Release+Asserts builds.
+ assert(assume(State, Cond, false) && "System is over constrained.");
+ return ProgramStatePair(NULL, State);
+ }
+
+ ProgramStateRef StFalse = assume(State, Cond, false);
+ if (!StFalse) {
+ // We are careful to return the original state, /not/ StTrue,
+ // because we want to avoid having callers generate a new node
+ // in the ExplodedGraph.
+ return ProgramStatePair(State, NULL);
+ }
+
+ return ProgramStatePair(StTrue, StFalse);
}
/// \brief If a symbol is perfectly constrained to a constant, attempt