Skip to content

Commit

Permalink
[analyzer] Rename assumeWithinInclusiveRange*()
Browse files Browse the repository at this point in the history
Summary: The name is slightly confusing, since the constraint is not necessarily within the range unless `Assumption` is true. Split out renaming for ConstraintManager.h from D26061

Reviewers: zaks.anna, dcoughlin

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D26644

llvm-svn: 286927
  • Loading branch information
ddcc committed Nov 15, 2016
1 parent 2b0a7be commit 3f8c3fa
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 62 deletions.
Expand Up @@ -36,7 +36,7 @@ class ConditionTruthVal {

/// Construct a ConstraintVal indicating the constraint is underconstrained.
ConditionTruthVal() {}

/// Return true if the constraint is perfectly constrained to 'true'.
bool isConstrainedTrue() const {
return Val.hasValue() && Val.getValue();
Expand All @@ -58,11 +58,11 @@ class ConditionTruthVal {
return !Val.hasValue();
}
};

class ConstraintManager {
public:
ConstraintManager() : NotifyAssumeClients(true) {}

virtual ~ConstraintManager();
virtual ProgramStateRef assume(ProgramStateRef state,
DefinedSVal Cond,
Expand Down Expand Up @@ -99,25 +99,26 @@ class ConstraintManager {
return ProgramStatePair(StTrue, StFalse);
}

virtual ProgramStateRef assumeWithinInclusiveRange(ProgramStateRef State,
NonLoc Value,
const llvm::APSInt &From,
const llvm::APSInt &To,
bool InBound) = 0;
virtual ProgramStateRef assumeInclusiveRange(ProgramStateRef State,
NonLoc Value,
const llvm::APSInt &From,
const llvm::APSInt &To,
bool InBound) = 0;

virtual ProgramStatePair assumeWithinInclusiveRangeDual(
ProgramStateRef State, NonLoc Value, const llvm::APSInt &From,
const llvm::APSInt &To) {
ProgramStateRef StInRange = assumeWithinInclusiveRange(State, Value, From,
To, true);
virtual ProgramStatePair assumeInclusiveRangeDual(ProgramStateRef State,
NonLoc Value,
const llvm::APSInt &From,
const llvm::APSInt &To) {
ProgramStateRef StInRange =
assumeInclusiveRange(State, Value, From, To, true);

// If StTrue is infeasible, asserting the falseness of Cond is unnecessary
// because the existing constraints already establish this.
if (!StInRange)
return ProgramStatePair((ProgramStateRef)nullptr, State);

ProgramStateRef StOutOfRange = assumeWithinInclusiveRange(State, Value,
From, To, false);
ProgramStateRef StOutOfRange =
assumeInclusiveRange(State, Value, From, To, false);
if (!StOutOfRange) {
// We are careful to return the original state, /not/ StTrue,
// because we want to avoid having callers generate a new node
Expand Down Expand Up @@ -147,7 +148,7 @@ class ConstraintManager {
const char *sep) = 0;

virtual void EndPath(ProgramStateRef state) {}

/// Convenience method to query the state to see if a symbol is null or
/// not null, or if neither assumption can be made.
ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym) {
Expand All @@ -173,7 +174,7 @@ class ConstraintManager {
virtual bool canReasonAbout(SVal X) const = 0;

/// Returns whether or not a symbol is known to be null ("true"), known to be
/// non-null ("false"), or may be either ("underconstrained").
/// non-null ("false"), or may be either ("underconstrained").
virtual ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym);
};

Expand Down
Expand Up @@ -98,18 +98,18 @@ class ProgramState : public llvm::FoldingSetNode {
/// This ctor is used when creating the first ProgramState object.
ProgramState(ProgramStateManager *mgr, const Environment& env,
StoreRef st, GenericDataMap gdm);

/// Copy ctor - We must explicitly define this or else the "Next" ptr
/// in FoldingSetNode will also get copied.
ProgramState(const ProgramState &RHS);

~ProgramState();

/// Return the ProgramStateManager associated with this state.
ProgramStateManager &getStateManager() const {
return *stateMgr;
}

/// Return the ConstraintManager.
ConstraintManager &getConstraintManager() const;

Expand All @@ -121,7 +121,7 @@ class ProgramState : public llvm::FoldingSetNode {
/// is a mapping from locations to values.
Store getStore() const { return store; }


/// getGDM - Return the generic data map associated with this state.
GenericDataMap getGDM() const { return GDM; }

Expand Down Expand Up @@ -197,25 +197,24 @@ class ProgramState : public llvm::FoldingSetNode {
///
/// This returns a new state with the added constraint on \p cond.
/// If no new state is feasible, NULL is returned.
ProgramStateRef assumeWithinInclusiveRange(DefinedOrUnknownSVal Val,
const llvm::APSInt &From,
const llvm::APSInt &To,
bool assumption) const;
ProgramStateRef assumeInclusiveRange(DefinedOrUnknownSVal Val,
const llvm::APSInt &From,
const llvm::APSInt &To,
bool assumption) const;

/// Assumes given range both "true" and "false" for \p Val, and returns both
/// corresponding states (respectively).
///
/// This is more efficient than calling assume() twice. Note that one (but not
/// both) of the returned states may be NULL.
std::pair<ProgramStateRef, ProgramStateRef>
assumeWithinInclusiveRange(DefinedOrUnknownSVal Val, const llvm::APSInt &From,
const llvm::APSInt &To) const;
assumeInclusiveRange(DefinedOrUnknownSVal Val, const llvm::APSInt &From,
const llvm::APSInt &To) const;


/// \brief Check if the given SVal is constrained to zero or is a zero
/// constant.
ConditionTruthVal isNull(SVal V) const;

/// Utility method for getting regions.
const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;

Expand Down Expand Up @@ -254,7 +253,7 @@ class ProgramState : public llvm::FoldingSetNode {
/// \param IS the set of invalidated symbols.
/// \param Call if non-null, the invalidated regions represent parameters to
/// the call and should be considered directly invalidated.
/// \param ITraits information about special handling for a particular
/// \param ITraits information about special handling for a particular
/// region/symbol.
ProgramStateRef
invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
Expand All @@ -278,7 +277,7 @@ class ProgramState : public llvm::FoldingSetNode {
/// Get the lvalue for a variable reference.
Loc getLValue(const VarDecl *D, const LocationContext *LC) const;

Loc getLValue(const CompoundLiteralExpr *literal,
Loc getLValue(const CompoundLiteralExpr *literal,
const LocationContext *LC) const;

/// Get the lvalue for an ivar reference.
Expand All @@ -295,7 +294,7 @@ class ProgramState : public llvm::FoldingSetNode {

/// Returns the SVal bound to the statement 'S' in the state's environment.
SVal getSVal(const Stmt *S, const LocationContext *LCtx) const;

SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const;

/// \brief Return the value bound to the specified location.
Expand All @@ -310,7 +309,7 @@ class ProgramState : public llvm::FoldingSetNode {
SVal getSVal(const MemRegion* R) const;

SVal getSValAsScalarOrLoc(const MemRegion *R) const;

/// \brief Visits the symbols reachable from the given SVal using the provided
/// SymbolVisitor.
///
Expand All @@ -319,22 +318,22 @@ class ProgramState : public llvm::FoldingSetNode {
/// visitor to avoid repeated initialization cost.
/// \sa ScanReachableSymbols
bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;

/// \brief Visits the symbols reachable from the SVals in the given range
/// using the provided SymbolVisitor.
bool scanReachableSymbols(const SVal *I, const SVal *E,
SymbolVisitor &visitor) const;

/// \brief Visits the symbols reachable from the regions in the given
/// MemRegions range using the provided SymbolVisitor.
bool scanReachableSymbols(const MemRegion * const *I,
bool scanReachableSymbols(const MemRegion * const *I,
const MemRegion * const *E,
SymbolVisitor &visitor) const;

template <typename CB> CB scanReachableSymbols(SVal val) const;
template <typename CB> CB scanReachableSymbols(const SVal *beg,
const SVal *end) const;

template <typename CB> CB
scanReachableSymbols(const MemRegion * const *beg,
const MemRegion * const *end) const;
Expand Down Expand Up @@ -469,7 +468,7 @@ class ProgramStateManager {

/// A BumpPtrAllocator to allocate states.
llvm::BumpPtrAllocator &Alloc;

/// A vector of ProgramStates that we can reuse.
std::vector<ProgramState *> freeStates;

Expand Down Expand Up @@ -632,9 +631,9 @@ class ProgramStateManager {
inline ConstraintManager &ProgramState::getConstraintManager() const {
return stateMgr->getConstraintManager();
}

inline const VarRegion* ProgramState::getRegion(const VarDecl *D,
const LocationContext *LC) const
const LocationContext *LC) const
{
return getStateManager().getRegionManager().getVarRegion(D, LC);
}
Expand All @@ -647,7 +646,7 @@ inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
return getStateManager().ConstraintMgr
->assume(this, Cond.castAs<DefinedSVal>(), Assumption);
}

inline std::pair<ProgramStateRef , ProgramStateRef >
ProgramState::assume(DefinedOrUnknownSVal Cond) const {
if (Cond.isUnknown())
Expand All @@ -657,31 +656,29 @@ ProgramState::assume(DefinedOrUnknownSVal Cond) const {
->assumeDual(this, Cond.castAs<DefinedSVal>());
}

inline ProgramStateRef
ProgramState::assumeWithinInclusiveRange(DefinedOrUnknownSVal Val,
const llvm::APSInt &From,
const llvm::APSInt &To,
bool Assumption) const {
inline ProgramStateRef ProgramState::assumeInclusiveRange(
DefinedOrUnknownSVal Val, const llvm::APSInt &From, const llvm::APSInt &To,
bool Assumption) const {
if (Val.isUnknown())
return this;

assert(Val.getAs<NonLoc>() && "Only NonLocs are supported!");

return getStateManager().ConstraintMgr->assumeWithinInclusiveRange(
this, Val.castAs<NonLoc>(), From, To, Assumption);
return getStateManager().ConstraintMgr->assumeInclusiveRange(
this, Val.castAs<NonLoc>(), From, To, Assumption);
}

inline std::pair<ProgramStateRef, ProgramStateRef>
ProgramState::assumeWithinInclusiveRange(DefinedOrUnknownSVal Val,
const llvm::APSInt &From,
const llvm::APSInt &To) const {
ProgramState::assumeInclusiveRange(DefinedOrUnknownSVal Val,
const llvm::APSInt &From,
const llvm::APSInt &To) const {
if (Val.isUnknown())
return std::make_pair(this, this);

assert(Val.getAs<NonLoc>() && "Only NonLocs are supported!");

return getStateManager().ConstraintMgr
->assumeWithinInclusiveRangeDual(this, Val.castAs<NonLoc>(), From, To);
return getStateManager().ConstraintMgr->assumeInclusiveRangeDual(
this, Val.castAs<NonLoc>(), From, To);
}

inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
Expand Down Expand Up @@ -810,7 +807,7 @@ CB ProgramState::scanReachableSymbols(SVal val) const {
scanReachableSymbols(val, cb);
return cb;
}

template <typename CB>
CB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
CB cb(this);
Expand Down
Expand Up @@ -254,7 +254,7 @@ ProgramStateRef StdLibraryFunctionsChecker::ValueRange::applyAsOutOfRange(
const llvm::APSInt &Min = BVF.getValue(R[I].first, T);
const llvm::APSInt &Max = BVF.getValue(R[I].second, T);
assert(Min <= Max);
State = CM.assumeWithinInclusiveRange(State, *N, Min, Max, false);
State = CM.assumeInclusiveRange(State, *N, Min, Max, false);
if (!State)
break;
}
Expand Down Expand Up @@ -288,15 +288,15 @@ StdLibraryFunctionsChecker::ValueRange::applyAsWithinRange(
const llvm::APSInt &Left = BVF.getValue(R[0].first - 1ULL, T);
if (Left != PlusInf) {
assert(MinusInf <= Left);
State = CM.assumeWithinInclusiveRange(State, *N, MinusInf, Left, false);
State = CM.assumeInclusiveRange(State, *N, MinusInf, Left, false);
if (!State)
return nullptr;
}

const llvm::APSInt &Right = BVF.getValue(R[E - 1].second + 1ULL, T);
if (Right != MinusInf) {
assert(Right <= PlusInf);
State = CM.assumeWithinInclusiveRange(State, *N, Right, PlusInf, false);
State = CM.assumeInclusiveRange(State, *N, Right, PlusInf, false);
if (!State)
return nullptr;
}
Expand All @@ -305,7 +305,7 @@ StdLibraryFunctionsChecker::ValueRange::applyAsWithinRange(
const llvm::APSInt &Min = BVF.getValue(R[I - 1].second + 1ULL, T);
const llvm::APSInt &Max = BVF.getValue(R[I].first - 1ULL, T);
assert(Min <= Max);
State = CM.assumeWithinInclusiveRange(State, *N, Min, Max, false);
State = CM.assumeInclusiveRange(State, *N, Min, Max, false);
if (!State)
return nullptr;
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
Expand Up @@ -1836,7 +1836,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
ProgramStateRef StateCase;
if (Optional<NonLoc> NL = CondV.getAs<NonLoc>())
std::tie(StateCase, DefaultSt) =
DefaultSt->assumeWithinInclusiveRange(*NL, V1, V2);
DefaultSt->assumeInclusiveRange(*NL, V1, V2);
else // UnknownVal
StateCase = DefaultSt;

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
Expand Up @@ -190,7 +190,7 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
} // end switch
}

ProgramStateRef SimpleConstraintManager::assumeWithinInclusiveRange(
ProgramStateRef SimpleConstraintManager::assumeInclusiveRange(
ProgramStateRef State, NonLoc Value, const llvm::APSInt &From,
const llvm::APSInt &To, bool InRange) {

Expand All @@ -207,7 +207,7 @@ ProgramStateRef SimpleConstraintManager::assumeWithinInclusiveRange(

switch (Value.getSubKind()) {
default:
llvm_unreachable("'assumeWithinInclusiveRange' is not implemented"
llvm_unreachable("'assumeInclusiveRange' is not implemented"
"for this NonLoc");

case nonloc::LocAsIntegerKind:
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.h
Expand Up @@ -38,7 +38,7 @@ class SimpleConstraintManager : public ConstraintManager {

ProgramStateRef assume(ProgramStateRef state, NonLoc Cond, bool Assumption);

ProgramStateRef assumeWithinInclusiveRange(ProgramStateRef State,
ProgramStateRef assumeInclusiveRange(ProgramStateRef State,
NonLoc Value,
const llvm::APSInt &From,
const llvm::APSInt &To,
Expand Down

0 comments on commit 3f8c3fa

Please sign in to comment.