summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-10-31 16:44:55 +0000
committerJordan Rose <jordan_rose@apple.com>2012-10-31 16:44:55 +0000
commit417591fba78efd32c2ae26fc9f57c6611a24754e (patch)
tree7d6cac2f0a9843f5e4c6ddd801082a4f912bf4bd /clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
parent70f4e794b5871be161a832a324063cce1ed18053 (diff)
downloadbcm5719-llvm-417591fba78efd32c2ae26fc9f57c6611a24754e.tar.gz
bcm5719-llvm-417591fba78efd32c2ae26fc9f57c6611a24754e.zip
[analyzer] Let ConstraintManager subclasses provide a more efficient checkNull.
Previously, every call to a ConstraintManager's isNull would do a full assumeDual to test feasibility. Now, ConstraintManagers can override checkNull if they have a cheaper way to do the same thing. RangeConstraintManager can do this in less than half the work. <rdar://problem/12608209> llvm-svn: 167138
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index a4c841eb6ba..467abd08378 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -324,6 +324,7 @@ public:
const llvm::APSInt& Adjustment);
const llvm::APSInt* getSymVal(ProgramStateRef St, SymbolRef sym) const;
+ ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym);
ProgramStateRef removeDeadBindings(ProgramStateRef St, SymbolReaper& SymReaper);
@@ -347,6 +348,30 @@ const llvm::APSInt* RangeConstraintManager::getSymVal(ProgramStateRef St,
return T ? T->getConcreteValue() : NULL;
}
+ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
+ SymbolRef Sym) {
+ const RangeSet *Ranges = State->get<ConstraintRange>(Sym);
+
+ // If we don't have any information about this symbol, it's underconstrained.
+ if (!Ranges)
+ return ConditionTruthVal();
+
+ // If we have a concrete value, see if it's zero.
+ if (const llvm::APSInt *Value = Ranges->getConcreteValue())
+ return *Value == 0;
+
+ BasicValueFactory &BV = getBasicVals();
+ APSIntType IntType = BV.getAPSIntType(Sym->getType());
+ llvm::APSInt Zero = IntType.getZeroValue();
+
+ // Check if zero is in the set of possible values.
+ if (Ranges->Intersect(BV, F, Zero, Zero).isEmpty())
+ return false;
+
+ // Zero is a possible value, but it is not the /only/ possible value.
+ return ConditionTruthVal();
+}
+
/// Scan all symbols referenced by the constraints. If the symbol is not alive
/// as marked in LSymbols, mark it as dead in DSymbols.
ProgramStateRef
OpenPOWER on IntegriCloud