File indexing completed on 2026-05-10 08:37:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
0014 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
0015
0016 #include "clang/Basic/LLVM.h"
0017 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
0018 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
0019 #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
0020 #include "llvm/Support/SaveAndRestore.h"
0021 #include <memory>
0022 #include <optional>
0023 #include <utility>
0024
0025 namespace llvm {
0026
0027 class APSInt;
0028
0029 }
0030
0031 namespace clang {
0032 namespace ento {
0033
0034 class ProgramStateManager;
0035 class ExprEngine;
0036 class SymbolReaper;
0037
0038 class ConditionTruthVal {
0039 std::optional<bool> Val;
0040
0041 public:
0042
0043
0044 ConditionTruthVal(bool constraint) : Val(constraint) {}
0045
0046
0047 ConditionTruthVal() = default;
0048
0049
0050
0051 bool getValue() const {
0052 return *Val;
0053 }
0054
0055
0056 bool isConstrainedTrue() const { return Val && *Val; }
0057
0058
0059 bool isConstrainedFalse() const { return Val && !*Val; }
0060
0061
0062 bool isConstrained() const { return Val.has_value(); }
0063
0064
0065
0066 bool isUnderconstrained() const { return !Val.has_value(); }
0067 };
0068
0069 class ConstraintManager {
0070 public:
0071 ConstraintManager() = default;
0072 virtual ~ConstraintManager();
0073
0074 virtual bool haveEqualConstraints(ProgramStateRef S1,
0075 ProgramStateRef S2) const = 0;
0076
0077 ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond,
0078 bool Assumption);
0079
0080 using ProgramStatePair = std::pair<ProgramStateRef, ProgramStateRef>;
0081
0082
0083
0084
0085
0086
0087 ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond);
0088
0089 ProgramStateRef assumeInclusiveRange(ProgramStateRef State, NonLoc Value,
0090 const llvm::APSInt &From,
0091 const llvm::APSInt &To, bool InBound);
0092
0093
0094
0095
0096
0097
0098 ProgramStatePair assumeInclusiveRangeDual(ProgramStateRef State, NonLoc Value,
0099 const llvm::APSInt &From,
0100 const llvm::APSInt &To);
0101
0102
0103
0104
0105
0106
0107
0108 virtual const llvm::APSInt* getSymVal(ProgramStateRef state,
0109 SymbolRef sym) const {
0110 return nullptr;
0111 }
0112
0113
0114
0115
0116 virtual const llvm::APSInt *getSymMinVal(ProgramStateRef state,
0117 SymbolRef sym) const {
0118 return nullptr;
0119 }
0120
0121
0122
0123
0124 virtual const llvm::APSInt *getSymMaxVal(ProgramStateRef state,
0125 SymbolRef sym) const {
0126 return nullptr;
0127 }
0128
0129
0130
0131 virtual ProgramStateRef removeDeadBindings(ProgramStateRef state,
0132 SymbolReaper& SymReaper) = 0;
0133
0134 virtual void printJson(raw_ostream &Out, ProgramStateRef State,
0135 const char *NL, unsigned int Space,
0136 bool IsDot) const = 0;
0137
0138 virtual void printValue(raw_ostream &Out, ProgramStateRef State,
0139 SymbolRef Sym) {}
0140
0141
0142
0143 ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym) {
0144 return checkNull(State, Sym);
0145 }
0146
0147 protected:
0148
0149 class AssumeStackTy {
0150 public:
0151 void push(const ProgramState *S) { Aux.push_back(S); }
0152 void pop() { Aux.pop_back(); }
0153 bool contains(const ProgramState *S) const {
0154 return llvm::is_contained(Aux, S);
0155 }
0156
0157 private:
0158 llvm::SmallVector<const ProgramState *, 4> Aux;
0159 };
0160 AssumeStackTy AssumeStack;
0161
0162 virtual ProgramStateRef assumeInternal(ProgramStateRef state,
0163 DefinedSVal Cond, bool Assumption) = 0;
0164
0165 virtual ProgramStateRef assumeInclusiveRangeInternal(ProgramStateRef State,
0166 NonLoc Value,
0167 const llvm::APSInt &From,
0168 const llvm::APSInt &To,
0169 bool InBound) = 0;
0170
0171
0172
0173
0174
0175
0176 virtual bool canReasonAbout(SVal X) const = 0;
0177
0178
0179
0180 virtual ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym);
0181
0182 template <typename AssumeFunction>
0183 ProgramStatePair assumeDualImpl(ProgramStateRef &State,
0184 AssumeFunction &Assume);
0185 };
0186
0187 std::unique_ptr<ConstraintManager>
0188 CreateRangeConstraintManager(ProgramStateManager &statemgr,
0189 ExprEngine *exprengine);
0190
0191 std::unique_ptr<ConstraintManager>
0192 CreateZ3ConstraintManager(ProgramStateManager &statemgr,
0193 ExprEngine *exprengine);
0194
0195 }
0196 }
0197
0198 #endif