#include "clang/Basic/JsonSupport.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <iterator>
#include <optional>
usingnamespaceclang;
usingnamespaceento;
class OperatorRelationsTable { … };
RangeSet::ContainerType RangeSet::Factory::EmptySet{ … };
RangeSet RangeSet::Factory::add(RangeSet LHS, RangeSet RHS) { … }
RangeSet RangeSet::Factory::add(RangeSet Original, Range Element) { … }
RangeSet RangeSet::Factory::add(RangeSet Original, const llvm::APSInt &Point) { … }
RangeSet RangeSet::Factory::unite(RangeSet LHS, RangeSet RHS) { … }
RangeSet RangeSet::Factory::unite(RangeSet Original, Range R) { … }
RangeSet RangeSet::Factory::unite(RangeSet Original, llvm::APSInt Point) { … }
RangeSet RangeSet::Factory::unite(RangeSet Original, llvm::APSInt From,
llvm::APSInt To) { … }
template <typename T>
static void swapIterators(T &First, T &FirstEnd, T &Second, T &SecondEnd) { … }
RangeSet::ContainerType RangeSet::Factory::unite(const ContainerType &LHS,
const ContainerType &RHS) { … }
RangeSet RangeSet::Factory::getRangeSet(Range From) { … }
RangeSet RangeSet::Factory::makePersistent(ContainerType &&From) { … }
RangeSet::ContainerType *RangeSet::Factory::construct(ContainerType &&From) { … }
const llvm::APSInt &RangeSet::getMinValue() const { … }
const llvm::APSInt &RangeSet::getMaxValue() const { … }
bool clang::ento::RangeSet::isUnsigned() const { … }
uint32_t clang::ento::RangeSet::getBitWidth() const { … }
APSIntType clang::ento::RangeSet::getAPSIntType() const { … }
bool RangeSet::containsImpl(llvm::APSInt &Point) const { … }
bool RangeSet::pin(llvm::APSInt &Point) const { … }
bool RangeSet::pin(llvm::APSInt &Lower, llvm::APSInt &Upper) const { … }
RangeSet RangeSet::Factory::intersect(RangeSet What, llvm::APSInt Lower,
llvm::APSInt Upper) { … }
RangeSet RangeSet::Factory::intersect(const RangeSet::ContainerType &LHS,
const RangeSet::ContainerType &RHS) { … }
RangeSet RangeSet::Factory::intersect(RangeSet LHS, RangeSet RHS) { … }
RangeSet RangeSet::Factory::intersect(RangeSet LHS, llvm::APSInt Point) { … }
RangeSet RangeSet::Factory::negate(RangeSet What) { … }
RangeSet RangeSet::Factory::castTo(RangeSet What, APSIntType Ty) { … }
RangeSet RangeSet::Factory::castTo(RangeSet What, QualType T) { … }
RangeSet::ContainerType RangeSet::Factory::truncateTo(RangeSet What,
APSIntType Ty) { … }
RangeSet::ContainerType RangeSet::Factory::convertTo(RangeSet What,
APSIntType Ty) { … }
RangeSet::ContainerType RangeSet::Factory::promoteTo(RangeSet What,
APSIntType Ty) { … }
RangeSet RangeSet::Factory::deletePoint(RangeSet From,
const llvm::APSInt &Point) { … }
LLVM_DUMP_METHOD void Range::dump(raw_ostream &OS) const { … }
LLVM_DUMP_METHOD void Range::dump() const { … }
LLVM_DUMP_METHOD void RangeSet::dump(raw_ostream &OS) const { … }
LLVM_DUMP_METHOD void RangeSet::dump() const { … }
REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(…)
namespace {
class EquivalenceClass;
}
REGISTER_MAP_WITH_PROGRAMSTATE(…)
REGISTER_MAP_WITH_PROGRAMSTATE(…)
REGISTER_MAP_WITH_PROGRAMSTATE(…)
REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(…)
REGISTER_MAP_WITH_PROGRAMSTATE(…)
namespace {
class EquivalenceClass : public llvm::FoldingSetNode { … };
[[nodiscard]] LLVM_ATTRIBUTE_UNUSED bool
areFeasible(ConstraintRangeTy Constraints) { … }
[[nodiscard]] inline const RangeSet *getConstraint(ProgramStateRef State,
EquivalenceClass Class) { … }
[[nodiscard]] inline const RangeSet *getConstraint(ProgramStateRef State,
SymbolRef Sym) { … }
[[nodiscard]] ProgramStateRef setConstraint(ProgramStateRef State,
EquivalenceClass Class,
RangeSet Constraint) { … }
[[nodiscard]] ProgramStateRef setConstraints(ProgramStateRef State,
ConstraintRangeTy Constraints) { … }
std::optional<bool> meansEquality(const SymSymExpr *Sym) { … }
template <class SecondTy, class... RestTy>
[[nodiscard]] inline RangeSet intersect(RangeSet::Factory &F, RangeSet Head,
SecondTy Second, RestTy... Tail);
template <class... RangeTy> struct IntersectionTraits;
IntersectionTraits<RangeSet, TailTy...>;
template <> struct IntersectionTraits<> { … };
IntersectionTraits<OptionalOrPointer, TailTy...>;
template <class EndTy>
[[nodiscard]] inline EndTy intersect(RangeSet::Factory &F, EndTy End) { … }
[[nodiscard]] LLVM_ATTRIBUTE_UNUSED inline std::optional<RangeSet>
intersect(RangeSet::Factory &F, const RangeSet *End) { … }
template <class... RestTy>
[[nodiscard]] inline RangeSet intersect(RangeSet::Factory &F, RangeSet Head,
RangeSet Second, RestTy... Tail) { … }
template <class SecondTy, class... RestTy>
[[nodiscard]] inline RangeSet intersect(RangeSet::Factory &F, RangeSet Head,
SecondTy Second, RestTy... Tail) { … }
template <class HeadTy, class SecondTy, class... RestTy>
[[nodiscard]] inline
typename IntersectionTraits<HeadTy, SecondTy, RestTy...>::Type
intersect(RangeSet::Factory &F, HeadTy Head, SecondTy Second,
RestTy... Tail) { … }
class SymbolicRangeInferrer
: public SymExprVisitor<SymbolicRangeInferrer, RangeSet> { … };
template <>
RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_NE>(RangeSet LHS,
RangeSet RHS,
QualType T) { … }
template <>
RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_Or>(Range LHS, Range RHS,
QualType T) { … }
template <>
RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_And>(Range LHS,
Range RHS,
QualType T) { … }
template <>
RangeSet SymbolicRangeInferrer::VisitBinaryOperator<BO_Rem>(Range LHS,
Range RHS,
QualType T) { … }
RangeSet SymbolicRangeInferrer::VisitBinaryOperator(RangeSet LHS,
BinaryOperator::Opcode Op,
RangeSet RHS, QualType T) { … }
class RangeConstraintManager : public RangedConstraintManager { … };
template <class Derived> class ConstraintAssignorBase { … } … };
class ConstraintAssignor : public ConstraintAssignorBase<ConstraintAssignor> { … };
bool ConstraintAssignor::assignSymExprToConst(const SymExpr *Sym,
const llvm::APSInt &Constraint) { … }
bool ConstraintAssignor::assignSymSymExprToRangeSet(const SymSymExpr *Sym,
RangeSet Constraint) { … }
}
std::unique_ptr<ConstraintManager>
ento::CreateRangeConstraintManager(ProgramStateManager &StMgr,
ExprEngine *Eng) { … }
ConstraintMap ento::getConstraintMap(ProgramStateRef State) { … }
LLVM_DUMP_METHOD void EquivalenceClass::dumpToStream(ProgramStateRef State,
raw_ostream &os) const { … }
inline EquivalenceClass EquivalenceClass::find(ProgramStateRef State,
SymbolRef Sym) { … }
inline ProgramStateRef EquivalenceClass::merge(RangeSet::Factory &F,
ProgramStateRef State,
SymbolRef First,
SymbolRef Second) { … }
inline ProgramStateRef EquivalenceClass::merge(RangeSet::Factory &F,
ProgramStateRef State,
EquivalenceClass Other) { … }
inline ProgramStateRef
EquivalenceClass::mergeImpl(RangeSet::Factory &RangeFactory,
ProgramStateRef State, SymbolSet MyMembers,
EquivalenceClass Other, SymbolSet OtherMembers) { … }
inline SymbolSet::Factory &
EquivalenceClass::getMembersFactory(ProgramStateRef State) { … }
SymbolSet EquivalenceClass::getClassMembers(ProgramStateRef State) const { … }
bool EquivalenceClass::isTrivial(ProgramStateRef State) const { … }
bool EquivalenceClass::isTriviallyDead(ProgramStateRef State,
SymbolReaper &Reaper) const { … }
inline ProgramStateRef EquivalenceClass::markDisequal(RangeSet::Factory &RF,
ProgramStateRef State,
SymbolRef First,
SymbolRef Second) { … }
inline ProgramStateRef EquivalenceClass::markDisequal(RangeSet::Factory &RF,
ProgramStateRef State,
EquivalenceClass First,
EquivalenceClass Second) { … }
inline ProgramStateRef
EquivalenceClass::markDisequal(RangeSet::Factory &RF, ProgramStateRef State,
EquivalenceClass Other) const { … }
inline bool EquivalenceClass::addToDisequalityInfo(
DisequalityMapTy &Info, ConstraintRangeTy &Constraints,
RangeSet::Factory &RF, ProgramStateRef State, EquivalenceClass First,
EquivalenceClass Second) { … }
inline std::optional<bool> EquivalenceClass::areEqual(ProgramStateRef State,
SymbolRef FirstSym,
SymbolRef SecondSym) { … }
inline std::optional<bool> EquivalenceClass::areEqual(ProgramStateRef State,
EquivalenceClass First,
EquivalenceClass Second) { … }
[[nodiscard]] ProgramStateRef
EquivalenceClass::removeMember(ProgramStateRef State, const SymbolRef Old) { … }
[[nodiscard]] static ProgramStateRef
reAssume(ProgramStateRef State, const RangeSet *Constraint, SVal TheValue) { … }
[[nodiscard]] ProgramStateRef
EquivalenceClass::simplify(SValBuilder &SVB, RangeSet::Factory &F,
ProgramStateRef State, EquivalenceClass Class) { … }
inline ClassSet EquivalenceClass::getDisequalClasses(ProgramStateRef State,
SymbolRef Sym) { … }
inline ClassSet
EquivalenceClass::getDisequalClasses(ProgramStateRef State) const { … }
inline ClassSet
EquivalenceClass::getDisequalClasses(DisequalityMapTy Map,
ClassSet::Factory &Factory) const { … }
bool EquivalenceClass::isClassDataConsistent(ProgramStateRef State) { … }
bool RangeConstraintManager::canReasonAbout(SVal X) const { … }
ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
SymbolRef Sym) { … }
const llvm::APSInt *RangeConstraintManager::getSymVal(ProgramStateRef St,
SymbolRef Sym) const { … }
const llvm::APSInt *RangeConstraintManager::getSymMinVal(ProgramStateRef St,
SymbolRef Sym) const { … }
const llvm::APSInt *RangeConstraintManager::getSymMaxVal(ProgramStateRef St,
SymbolRef Sym) const { … }
ProgramStateRef
RangeConstraintManager::removeDeadBindings(ProgramStateRef State,
SymbolReaper &SymReaper) { … }
RangeSet RangeConstraintManager::getRange(ProgramStateRef State,
SymbolRef Sym) { … }
ProgramStateRef RangeConstraintManager::setRange(ProgramStateRef State,
SymbolRef Sym,
RangeSet Range) { … }
ProgramStateRef
RangeConstraintManager::assumeSymNE(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) { … }
ProgramStateRef
RangeConstraintManager::assumeSymEQ(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) { … }
RangeSet RangeConstraintManager::getSymLTRange(ProgramStateRef St,
SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) { … }
ProgramStateRef
RangeConstraintManager::assumeSymLT(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) { … }
RangeSet RangeConstraintManager::getSymGTRange(ProgramStateRef St,
SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) { … }
ProgramStateRef
RangeConstraintManager::assumeSymGT(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) { … }
RangeSet RangeConstraintManager::getSymGERange(ProgramStateRef St,
SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) { … }
ProgramStateRef
RangeConstraintManager::assumeSymGE(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) { … }
RangeSet
RangeConstraintManager::getSymLERange(llvm::function_ref<RangeSet()> RS,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) { … }
RangeSet RangeConstraintManager::getSymLERange(ProgramStateRef St,
SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) { … }
ProgramStateRef
RangeConstraintManager::assumeSymLE(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) { … }
ProgramStateRef RangeConstraintManager::assumeSymWithinInclusiveRange(
ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
const llvm::APSInt &To, const llvm::APSInt &Adjustment) { … }
ProgramStateRef RangeConstraintManager::assumeSymOutsideInclusiveRange(
ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
const llvm::APSInt &To, const llvm::APSInt &Adjustment) { … }
void RangeConstraintManager::printJson(raw_ostream &Out, ProgramStateRef State,
const char *NL, unsigned int Space,
bool IsDot) const { … }
void RangeConstraintManager::printValue(raw_ostream &Out, ProgramStateRef State,
SymbolRef Sym) { … }
static std::string toString(const SymbolRef &Sym) { … }
void RangeConstraintManager::printConstraints(raw_ostream &Out,
ProgramStateRef State,
const char *NL,
unsigned int Space,
bool IsDot) const { … }
static std::string toString(ProgramStateRef State, EquivalenceClass Class) { … }
void RangeConstraintManager::printEquivalenceClasses(raw_ostream &Out,
ProgramStateRef State,
const char *NL,
unsigned int Space,
bool IsDot) const { … }
void RangeConstraintManager::printDisequalities(raw_ostream &Out,
ProgramStateRef State,
const char *NL,
unsigned int Space,
bool IsDot) const { … }