forked from OSchip/llvm-project
[analyzer][NFC] Factor out the copy-paste code repetition of assumeDual and assumeInclusiveRangeDual
Depends on D125892. There might be efficiency and performance implications by using a lambda. Thus, I am going to conduct measurements to see if there is any noticeable impact. I've been thinking about two more alternatives: 1) Make `assumeDualImpl` a variadic template and (perfect) forward the arguments for the used `assume` function. 2) Use a macros. I have concerns though, whether these alternatives would deteriorate the readability of the code. Differential Revision: https://reviews.llvm.org/D125954
This commit is contained in:
parent
32f189b0d9
commit
96fba640cf
|
@ -162,6 +162,10 @@ protected:
|
|||
/// Returns whether or not a symbol is known to be null ("true"), known to be
|
||||
/// non-null ("false"), or may be either ("underconstrained").
|
||||
virtual ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym);
|
||||
|
||||
template <typename AssumeFunction>
|
||||
ProgramStatePair assumeDualImpl(ProgramStateRef &State,
|
||||
AssumeFunction &Assume);
|
||||
};
|
||||
|
||||
std::unique_ptr<ConstraintManager>
|
||||
|
|
|
@ -42,12 +42,14 @@ ConditionTruthVal ConstraintManager::checkNull(ProgramStateRef State,
|
|||
return {};
|
||||
}
|
||||
|
||||
template <typename AssumeFunction>
|
||||
ConstraintManager::ProgramStatePair
|
||||
ConstraintManager::assumeDual(ProgramStateRef State, DefinedSVal Cond) {
|
||||
ProgramStateRef StTrue = assumeInternal(State, Cond, true);
|
||||
ConstraintManager::assumeDualImpl(ProgramStateRef &State,
|
||||
AssumeFunction &Assume) {
|
||||
ProgramStateRef StTrue = Assume(true);
|
||||
|
||||
if (!StTrue) {
|
||||
ProgramStateRef StFalse = assumeInternal(State, Cond, false);
|
||||
ProgramStateRef StFalse = Assume(false);
|
||||
if (LLVM_UNLIKELY(!StFalse)) { // both infeasible
|
||||
ProgramStateRef StInfeasible = State->cloneAsPosteriorlyOverconstrained();
|
||||
assert(StInfeasible->isPosteriorlyOverconstrained());
|
||||
|
@ -63,7 +65,7 @@ ConstraintManager::assumeDual(ProgramStateRef State, DefinedSVal Cond) {
|
|||
return ProgramStatePair(nullptr, StFalse);
|
||||
}
|
||||
|
||||
ProgramStateRef StFalse = assumeInternal(State, Cond, false);
|
||||
ProgramStateRef StFalse = Assume(false);
|
||||
if (!StFalse) {
|
||||
return ProgramStatePair(StTrue, nullptr);
|
||||
}
|
||||
|
@ -71,36 +73,22 @@ ConstraintManager::assumeDual(ProgramStateRef State, DefinedSVal Cond) {
|
|||
return ProgramStatePair(StTrue, StFalse);
|
||||
}
|
||||
|
||||
ConstraintManager::ProgramStatePair
|
||||
ConstraintManager::assumeDual(ProgramStateRef State, DefinedSVal Cond) {
|
||||
auto AssumeFun = [&](bool Assumption) {
|
||||
return assumeInternal(State, Cond, Assumption);
|
||||
};
|
||||
return assumeDualImpl(State, AssumeFun);
|
||||
}
|
||||
|
||||
ConstraintManager::ProgramStatePair
|
||||
ConstraintManager::assumeInclusiveRangeDual(ProgramStateRef State, NonLoc Value,
|
||||
const llvm::APSInt &From,
|
||||
const llvm::APSInt &To) {
|
||||
ProgramStateRef StInRange =
|
||||
assumeInclusiveRangeInternal(State, Value, From, To, true);
|
||||
if (!StInRange) {
|
||||
ProgramStateRef StOutOfRange =
|
||||
assumeInclusiveRangeInternal(State, Value, From, To, false);
|
||||
if (LLVM_UNLIKELY(!StOutOfRange)) { // both infeasible
|
||||
ProgramStateRef StInfeasible = State->cloneAsPosteriorlyOverconstrained();
|
||||
assert(StInfeasible->isPosteriorlyOverconstrained());
|
||||
// Checkers might rely on the API contract that both returned states
|
||||
// cannot be null. Thus, we return StInfeasible for both branches because
|
||||
// it might happen that a Checker uncoditionally uses one of them if the
|
||||
// other is a nullptr. This may also happen with the non-dual and
|
||||
// adjacent `assume(true)` and `assume(false)` calls. By implementing
|
||||
// assume in therms of assumeDual, we can keep our API contract there as
|
||||
// well.
|
||||
return ProgramStatePair(StInfeasible, StInfeasible);
|
||||
}
|
||||
}
|
||||
|
||||
ProgramStateRef StOutOfRange =
|
||||
assumeInclusiveRangeInternal(State, Value, From, To, false);
|
||||
if (!StOutOfRange) {
|
||||
return ProgramStatePair(StInRange, nullptr);
|
||||
}
|
||||
|
||||
return ProgramStatePair(StInRange, StOutOfRange);
|
||||
auto AssumeFun = [&](bool Assumption) {
|
||||
return assumeInclusiveRangeInternal(State, Value, From, To, Assumption);
|
||||
};
|
||||
return assumeDualImpl(State, AssumeFun);
|
||||
}
|
||||
|
||||
ProgramStateRef ConstraintManager::assume(ProgramStateRef State,
|
||||
|
|
Loading…
Reference in New Issue