File indexing completed on 2026-05-10 08:37:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALBUILDER_H
0015 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALBUILDER_H
0016
0017 #include "clang/AST/ASTContext.h"
0018 #include "clang/AST/DeclarationName.h"
0019 #include "clang/AST/Expr.h"
0020 #include "clang/AST/ExprObjC.h"
0021 #include "clang/AST/Type.h"
0022 #include "clang/Basic/LLVM.h"
0023 #include "clang/Basic/LangOptions.h"
0024 #include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
0025 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
0026 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
0027 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
0028 #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
0029 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
0030 #include "llvm/ADT/ImmutableList.h"
0031 #include <cstdint>
0032 #include <optional>
0033
0034 namespace clang {
0035
0036 class AnalyzerOptions;
0037 class BlockDecl;
0038 class CXXBoolLiteralExpr;
0039 class CXXMethodDecl;
0040 class CXXRecordDecl;
0041 class DeclaratorDecl;
0042 class FunctionDecl;
0043 class LocationContext;
0044 class StackFrameContext;
0045 class Stmt;
0046
0047 namespace ento {
0048
0049 class ConditionTruthVal;
0050 class ProgramStateManager;
0051 class StoreRef;
0052
0053 class SValBuilder {
0054 virtual void anchor();
0055
0056 protected:
0057 ASTContext &Context;
0058
0059
0060 BasicValueFactory BasicVals;
0061
0062
0063 SymbolManager SymMgr;
0064
0065
0066 MemRegionManager MemMgr;
0067
0068 ProgramStateManager &StateMgr;
0069
0070 const AnalyzerOptions &AnOpts;
0071
0072
0073 const QualType ArrayIndexTy;
0074
0075
0076 const unsigned ArrayIndexWidth;
0077
0078 public:
0079 SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
0080 ProgramStateManager &stateMgr);
0081
0082 virtual ~SValBuilder() = default;
0083
0084 SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy);
0085
0086
0087 SVal evalIntegralCast(ProgramStateRef state, SVal val, QualType castTy,
0088 QualType originalType);
0089
0090 SVal evalMinus(NonLoc val);
0091 SVal evalComplement(NonLoc val);
0092
0093
0094
0095 virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op,
0096 NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
0097
0098
0099
0100 virtual SVal evalBinOpLL(ProgramStateRef state, BinaryOperator::Opcode op,
0101 Loc lhs, Loc rhs, QualType resultTy) = 0;
0102
0103
0104
0105
0106 virtual SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op,
0107 Loc lhs, NonLoc rhs, QualType resultTy) = 0;
0108
0109
0110
0111 virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal val) = 0;
0112
0113
0114
0115
0116
0117 virtual const llvm::APSInt *getMinValue(ProgramStateRef state, SVal val) = 0;
0118
0119
0120
0121
0122
0123 virtual const llvm::APSInt *getMaxValue(ProgramStateRef state, SVal val) = 0;
0124
0125
0126
0127
0128 virtual SVal simplifySVal(ProgramStateRef State, SVal Val) = 0;
0129
0130
0131 SVal makeSymExprValNN(BinaryOperator::Opcode op,
0132 NonLoc lhs, NonLoc rhs, QualType resultTy);
0133
0134 SVal evalUnaryOp(ProgramStateRef state, UnaryOperator::Opcode opc,
0135 SVal operand, QualType type);
0136
0137 SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
0138 SVal lhs, SVal rhs, QualType type);
0139
0140
0141 ConditionTruthVal areEqual(ProgramStateRef state, SVal lhs, SVal rhs);
0142
0143 SVal evalEQ(ProgramStateRef state, SVal lhs, SVal rhs);
0144
0145 DefinedOrUnknownSVal evalEQ(ProgramStateRef state, DefinedOrUnknownSVal lhs,
0146 DefinedOrUnknownSVal rhs);
0147
0148 ASTContext &getContext() { return Context; }
0149 const ASTContext &getContext() const { return Context; }
0150
0151 ProgramStateManager &getStateManager() { return StateMgr; }
0152
0153 QualType getConditionType() const {
0154 return Context.getLangOpts().CPlusPlus ? Context.BoolTy : Context.IntTy;
0155 }
0156
0157 QualType getArrayIndexType() const {
0158 return ArrayIndexTy;
0159 }
0160
0161 BasicValueFactory &getBasicValueFactory() { return BasicVals; }
0162 const BasicValueFactory &getBasicValueFactory() const { return BasicVals; }
0163
0164 SymbolManager &getSymbolManager() { return SymMgr; }
0165 const SymbolManager &getSymbolManager() const { return SymMgr; }
0166
0167 MemRegionManager &getRegionManager() { return MemMgr; }
0168 const MemRegionManager &getRegionManager() const { return MemMgr; }
0169
0170 const AnalyzerOptions &getAnalyzerOptions() const { return AnOpts; }
0171
0172
0173
0174 const SymbolConjured* conjureSymbol(const Stmt *stmt,
0175 const LocationContext *LCtx,
0176 QualType type,
0177 unsigned visitCount,
0178 const void *symbolTag = nullptr) {
0179 return SymMgr.conjureSymbol(stmt, LCtx, type, visitCount, symbolTag);
0180 }
0181
0182 const SymbolConjured* conjureSymbol(const Expr *expr,
0183 const LocationContext *LCtx,
0184 unsigned visitCount,
0185 const void *symbolTag = nullptr) {
0186 return SymMgr.conjureSymbol(expr, LCtx, visitCount, symbolTag);
0187 }
0188
0189
0190 DefinedOrUnknownSVal makeZeroVal(QualType type);
0191
0192
0193 DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedValueRegion *region);
0194
0195
0196
0197
0198
0199
0200
0201 DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag,
0202 const Expr *expr,
0203 const LocationContext *LCtx,
0204 unsigned count);
0205 DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Stmt *S,
0206 const LocationContext *LCtx,
0207 QualType type, unsigned count);
0208 DefinedOrUnknownSVal conjureSymbolVal(const Stmt *stmt,
0209 const LocationContext *LCtx,
0210 QualType type,
0211 unsigned visitCount);
0212
0213
0214
0215
0216 DefinedSVal getConjuredHeapSymbolVal(const Expr *E,
0217 const LocationContext *LCtx,
0218 unsigned Count);
0219
0220
0221
0222
0223
0224 DefinedSVal getConjuredHeapSymbolVal(const Expr *E,
0225 const LocationContext *LCtx,
0226 QualType type, unsigned Count);
0227
0228
0229
0230
0231
0232
0233 loc::MemRegionVal getAllocaRegionVal(const Expr *E,
0234 const LocationContext *LCtx,
0235 unsigned Count);
0236
0237 DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(
0238 SymbolRef parentSymbol, const TypedValueRegion *region);
0239
0240 DefinedSVal getMetadataSymbolVal(const void *symbolTag,
0241 const MemRegion *region,
0242 const Expr *expr, QualType type,
0243 const LocationContext *LCtx,
0244 unsigned count);
0245
0246 DefinedSVal getMemberPointer(const NamedDecl *ND);
0247
0248 DefinedSVal getFunctionPointer(const FunctionDecl *func);
0249
0250 DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy,
0251 const LocationContext *locContext,
0252 unsigned blockCount);
0253
0254
0255
0256
0257
0258 std::optional<SVal> getConstantVal(const Expr *E);
0259
0260 NonLoc makeCompoundVal(QualType type, llvm::ImmutableList<SVal> vals) {
0261 return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals));
0262 }
0263
0264 NonLoc makeLazyCompoundVal(const StoreRef &store,
0265 const TypedValueRegion *region) {
0266 return nonloc::LazyCompoundVal(
0267 BasicVals.getLazyCompoundValData(store, region));
0268 }
0269
0270 NonLoc makePointerToMember(const DeclaratorDecl *DD) {
0271 return nonloc::PointerToMember(DD);
0272 }
0273
0274 NonLoc makePointerToMember(const PointerToMemberData *PTMD) {
0275 return nonloc::PointerToMember(PTMD);
0276 }
0277
0278 NonLoc makeZeroArrayIndex() {
0279 return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
0280 }
0281
0282 NonLoc makeArrayIndex(uint64_t idx) {
0283 return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy));
0284 }
0285
0286 SVal convertToArrayIndex(SVal val);
0287
0288 nonloc::ConcreteInt makeIntVal(const IntegerLiteral* integer) {
0289 return nonloc::ConcreteInt(
0290 BasicVals.getValue(integer->getValue(),
0291 integer->getType()->isUnsignedIntegerOrEnumerationType()));
0292 }
0293
0294 nonloc::ConcreteInt makeBoolVal(const ObjCBoolLiteralExpr *boolean) {
0295 return makeTruthVal(boolean->getValue(), boolean->getType());
0296 }
0297
0298 nonloc::ConcreteInt makeBoolVal(const CXXBoolLiteralExpr *boolean);
0299
0300 nonloc::ConcreteInt makeIntVal(const llvm::APSInt& integer) {
0301 return nonloc::ConcreteInt(BasicVals.getValue(integer));
0302 }
0303
0304 loc::ConcreteInt makeIntLocVal(const llvm::APSInt &integer) {
0305 return loc::ConcreteInt(BasicVals.getValue(integer));
0306 }
0307
0308 NonLoc makeIntVal(const llvm::APInt& integer, bool isUnsigned) {
0309 return nonloc::ConcreteInt(BasicVals.getValue(integer, isUnsigned));
0310 }
0311
0312 DefinedSVal makeIntVal(uint64_t integer, QualType type) {
0313 if (Loc::isLocType(type))
0314 return loc::ConcreteInt(BasicVals.getValue(integer, type));
0315
0316 return nonloc::ConcreteInt(BasicVals.getValue(integer, type));
0317 }
0318
0319 NonLoc makeIntVal(uint64_t integer, bool isUnsigned) {
0320 return nonloc::ConcreteInt(BasicVals.getIntValue(integer, isUnsigned));
0321 }
0322
0323 NonLoc makeIntValWithWidth(QualType ptrType, uint64_t integer) {
0324 return nonloc::ConcreteInt(BasicVals.getValue(integer, ptrType));
0325 }
0326
0327 NonLoc makeLocAsInteger(Loc loc, unsigned bits) {
0328 return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(loc, bits));
0329 }
0330
0331 nonloc::SymbolVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
0332 APSIntPtr rhs, QualType type);
0333
0334 nonloc::SymbolVal makeNonLoc(APSIntPtr rhs, BinaryOperator::Opcode op,
0335 const SymExpr *lhs, QualType type);
0336
0337 nonloc::SymbolVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
0338 const SymExpr *rhs, QualType type);
0339
0340 NonLoc makeNonLoc(const SymExpr *operand, UnaryOperator::Opcode op,
0341 QualType type);
0342
0343
0344 nonloc::SymbolVal makeNonLoc(const SymExpr *operand, QualType fromTy,
0345 QualType toTy);
0346
0347 nonloc::ConcreteInt makeTruthVal(bool b, QualType type) {
0348 return nonloc::ConcreteInt(BasicVals.getTruthValue(b, type));
0349 }
0350
0351 nonloc::ConcreteInt makeTruthVal(bool b) {
0352 return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
0353 }
0354
0355
0356
0357
0358 loc::ConcreteInt makeNullWithType(QualType type) {
0359
0360 assert((type->isPointerType() || type->isObjCObjectPointerType() ||
0361 type->isBlockPointerType() || type->isNullPtrType() ||
0362 type->isReferenceType()) &&
0363 "makeNullWithType must use pointer type");
0364
0365
0366
0367
0368 type = type->isReferenceType()
0369 ? Context.getPointerType(type->getPointeeType())
0370 : type;
0371 return loc::ConcreteInt(BasicVals.getZeroWithTypeSize(type));
0372 }
0373
0374 loc::MemRegionVal makeLoc(SymbolRef sym) {
0375 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
0376 }
0377
0378 loc::MemRegionVal makeLoc(const MemRegion *region) {
0379 return loc::MemRegionVal(region);
0380 }
0381
0382 loc::GotoLabel makeLoc(const AddrLabelExpr *expr) {
0383 return loc::GotoLabel(expr->getLabel());
0384 }
0385
0386 loc::ConcreteInt makeLoc(const llvm::APSInt &integer) {
0387 return loc::ConcreteInt(BasicVals.getValue(integer));
0388 }
0389
0390
0391 std::optional<loc::MemRegionVal>
0392 getCastedMemRegionVal(const MemRegion *region, QualType type);
0393
0394
0395
0396
0397 DefinedSVal makeSymbolVal(SymbolRef Sym) {
0398 if (Loc::isLocType(Sym->getType()))
0399 return makeLoc(Sym);
0400 return nonloc::SymbolVal(Sym);
0401 }
0402
0403
0404 loc::MemRegionVal getCXXThis(const CXXMethodDecl *D,
0405 const StackFrameContext *SFC);
0406
0407
0408 loc::MemRegionVal getCXXThis(const CXXRecordDecl *D,
0409 const StackFrameContext *SFC);
0410 };
0411
0412 SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
0413 ASTContext &context,
0414 ProgramStateManager &stateMgr);
0415
0416 }
0417
0418 }
0419
0420 #endif