diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core')
-rw-r--r-- | lib/StaticAnalyzer/Core/ConstraintManager.cpp | 10 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/RangeConstraintManager.cpp | 25 |
2 files changed, 27 insertions, 8 deletions
diff --git a/lib/StaticAnalyzer/Core/ConstraintManager.cpp b/lib/StaticAnalyzer/Core/ConstraintManager.cpp index 5dd1392bde..4dec526005 100644 --- a/lib/StaticAnalyzer/Core/ConstraintManager.cpp +++ b/lib/StaticAnalyzer/Core/ConstraintManager.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" -#include "llvm/Support/SaveAndRestore.h" using namespace clang; using namespace ento; @@ -26,13 +25,8 @@ static DefinedSVal getLocFromSymbol(const ProgramStateRef &State, return loc::MemRegionVal(R); } -/// Convenience method to query the state to see if a symbol is null or -/// not null, or neither assumption can be made. -ConditionTruthVal ConstraintManager::isNull(ProgramStateRef State, - SymbolRef Sym) { - // Disable recursive notification of clients. - llvm::SaveAndRestore<bool> DisableNotify(NotifyAssumeClients, false); - +ConditionTruthVal ConstraintManager::checkNull(ProgramStateRef State, + SymbolRef Sym) { QualType Ty = Sym->getType(); DefinedSVal V = Loc::isLocType(Ty) ? getLocFromSymbol(State, Sym) : nonloc::SymbolVal(Sym); diff --git a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp index a4c841eb6b..467abd0837 100644 --- a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ b/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 |