diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-10-31 16:44:55 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-10-31 16:44:55 +0000 |
commit | 417591fba78efd32c2ae26fc9f57c6611a24754e (patch) | |
tree | 7d6cac2f0a9843f5e4c6ddd801082a4f912bf4bd /clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp | |
parent | 70f4e794b5871be161a832a324063cce1ed18053 (diff) | |
download | bcm5719-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.cpp | 25 |
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 |