Go to the documentation of this file.
35 #include "llvm/ADT/APSInt.h"
36 #include "llvm/ADT/None.h"
37 #include "llvm/ADT/Optional.h"
38 #include "llvm/Support/Casting.h"
39 #include "llvm/Support/Compiler.h"
43 using namespace clang;
50 void SValBuilder::anchor() {}
54 : Context(context), BasicVals(context, alloc),
55 SymMgr(context, BasicVals, alloc), MemMgr(context, alloc),
58 stateMgr.getOwningEngine().getAnalysisManager().getAnalyzerOptions()),
59 ArrayIndexTy(context.LongLongTy),
60 ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {}
66 if (
type->isIntegralOrEnumerationType())
69 if (
type->isArrayType() ||
type->isRecordType() ||
type->isVectorType() ||
70 type->isAnyComplexType())
171 if (
type->isNullPtrType())
188 unsigned visitCount) {
189 if (
type->isNullPtrType())
206 unsigned VisitCount) {
217 if (
type->isNullPtrType())
260 assert(!ND || (isa<CXXMethodDecl, FieldDecl, IndirectFieldDecl>(ND)));
262 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
282 unsigned blockCount) {
318 case Stmt::AddrLabelExprClass:
319 return makeLoc(cast<AddrLabelExpr>(E));
321 case Stmt::CXXScalarValueInitExprClass:
322 case Stmt::ImplicitValueInitExprClass:
325 case Stmt::ObjCStringLiteralClass: {
326 const auto *SL = cast<ObjCStringLiteral>(E);
330 case Stmt::StringLiteralClass: {
331 const auto *SL = cast<StringLiteral>(E);
335 case Stmt::PredefinedExprClass: {
336 const auto *PE = cast<PredefinedExpr>(E);
337 assert(PE->getFunctionName() &&
338 "Since we analyze only instantiated functions, PredefinedExpr "
339 "should have a function name.");
345 case Stmt::CharacterLiteralClass: {
346 const auto *C = cast<CharacterLiteral>(E);
347 return makeIntVal(C->getValue(), C->getType());
350 case Stmt::CXXBoolLiteralExprClass:
353 case Stmt::TypeTraitExprClass: {
354 const auto *TE = cast<TypeTraitExpr>(E);
358 case Stmt::IntegerLiteralClass:
361 case Stmt::ObjCBoolLiteralExprClass:
364 case Stmt::CXXNullPtrLiteralExprClass:
367 case Stmt::CStyleCastExprClass:
368 case Stmt::CXXFunctionalCastExprClass:
369 case Stmt::CXXConstCastExprClass:
370 case Stmt::CXXReinterpretCastExprClass:
371 case Stmt::CXXStaticCastExprClass:
372 case Stmt::ImplicitCastExprClass: {
373 const auto *CE = cast<CastExpr>(E);
374 switch (CE->getCastKind()) {
377 case CK_ArrayToPointerDecay:
378 case CK_IntegralToPointer:
381 const Expr *SE = CE->getSubExpr();
420 const unsigned MaxComp =
AnOpts.MaxSymbolComplexity;
422 if (symLHS && symRHS &&
424 return makeNonLoc(symLHS, Op, symRHS, ResultTy);
428 return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
432 return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
450 if (op == BinaryOperatorKind::BO_Cmp) {
467 return Op == BO_Mul || Op == BO_Add || Op == BO_And || Op == BO_Xor ||
471 if (IsCommutative(op)) {
518 if (Quals1 != Quals2)
544 return evalCast(val, castTy, originalTy);
548 return evalCast(val, castTy, originalTy);
555 makeIntVal(ToTypeMax.isUnsigned() ? ToTypeMax.getZExtValue()
556 : ToTypeMax.getSExtValue(),
566 std::tie(IsNotTruncated, IsTruncated) =
state->assume(CompVal);
567 if (!IsNotTruncated && IsTruncated) {
571 return evalCast(val, castTy, originalTy);
597 const bool IsUnknownOriginalType = OriginalTy.
isNull();
598 if (!IsUnknownOriginalType) {
601 if (CastTy == OriginalTy)
614 switch (
V.getBaseKind()) {
615 case SVal::UndefinedValKind:
617 case SVal::UnknownValKind:
621 case SVal::NonLocKind:
625 llvm_unreachable(
"Unknown SVal kind");
639 switch (
V.getSubKind()) {
640 case loc::ConcreteIntKind:
642 case loc::GotoLabelKind:
644 case loc::MemRegionValKind:
648 llvm_unreachable(
"Unknown SVal kind");
652 switch (
V.getSubKind()) {
653 case nonloc::CompoundValKind:
655 case nonloc::ConcreteIntKind:
657 case nonloc::LazyCompoundValKind:
660 case nonloc::LocAsIntegerKind:
663 case nonloc::SymbolValKind:
665 case nonloc::PointerToMemberKind:
670 llvm_unreachable(
"Unknown SVal kind");
710 const bool IsUnknownOriginalType = OriginalTy.
isNull();
711 if (!IsUnknownOriginalType) {
713 if (isa<ArrayType>(OriginalTy))
737 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FTR->getDecl()))
758 const bool IsUnknownOriginalType = OriginalTy.
isNull();
760 const auto *ArrayTy =
761 IsUnknownOriginalType
771 QualType ElemTy = ArrayTy->getElementType();
785 if (IsUnknownOriginalType) {
796 if (
const auto *SR = dyn_cast<SymbolicRegion>(R)) {
797 QualType SRTy = SR->getSymbol()->getType();
806 if (
const auto *ER = dyn_cast<ElementRegion>(R)) {
824 QualType ElemTy = ArrayTy->getElementType();
877 auto CastedValue = [
V, CastTy,
this]() {
884 if (CastTy->isBooleanType())
888 if (CastTy->isIntegralOrEnumerationType())
914 const bool IsUnknownOriginalType = OriginalTy.
isNull();
926 if (!IsUnknownOriginalType && R) {
941 if (IsUnknownOriginalType)
950 SE = SR->getSymbol();
957 if (CastSize ==
V.getNumBits())
972 const bool IsUnknownOriginalType = OriginalTy.
isNull();
994 if (!Opts.ShouldSupportSymbolicIntegerCasts)
1055 if (!isa<SymbolCast>(SE))
1058 SymbolRef RootSym = cast<SymbolCast>(SE)->getOperand();
1069 const bool isSameType = (RT == CastTy);
1080 if (((WT > WR) && (UR || !UT)) || ((WT == WR) && (UT == UR)))
QualType getThisType() const
Return the type of the this pointer.
ExprEngine & getOwningEngine()
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type)
static bool isLocType(QualType T)
ASTContext & getASTContext() const
A boolean literal, per ([C++ lex.bool] Boolean literals).
llvm::ImmutableList< SVal > getEmptySValList()
bool isBlockPointerType() const
const SymbolConjured * conjureSymbol(const Stmt *E, const LocationContext *LCtx, QualType T, unsigned VisitCount, const void *SymbolTag=nullptr)
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
bool isVoidPointerType() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
ProgramStateManager & StateMgr
DefinedSVal getMetadataSymbolVal(const void *symbolTag, const MemRegion *region, const Expr *expr, QualType type, const LocationContext *LCtx, unsigned count)
const MemRegion * getAsRegion() const
NonLoc makeLocAsInteger(Loc loc, unsigned bits)
const IntSymExpr * getIntSymExpr(const llvm::APSInt &lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t)
const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
unsigned getIntWidth(QualType T) const
This represents a decl that may have a name.
virtual unsigned computeComplexity() const =0
const SymSymExpr * getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t)
loc::ConcreteInt makeNullWithType(QualType type)
Create NULL pointer, with proper pointer bit-width for given address space.
A (possibly-)qualified type.
const Type * getTypeForDecl() const
const SymbolicRegion * getSymbolicHeapRegion(SymbolRef sym)
Return a unique symbolic region belonging to heap memory space.
QualType getCanonicalType() const
bool isFloatingType() const
The collection of all-type qualifiers we support.
DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, const TypedValueRegion *region)
const SymExpr * SymbolRef
const BlockDataRegion * getBlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc, unsigned blockCount)
getBlockDataRegion - Get the memory region associated with an instance of a block.
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
bool isVariableArrayType() const
It represents a stack frame of the call stack (based on CallEvent).
Value representing integer constant.
const FunctionCodeRegion * getFunctionCodeRegion(const NamedDecl *FD)
DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E, const LocationContext *LCtx, unsigned Count)
Conjure a symbol representing heap allocated memory region.
llvm::APSInt getMaxValue() const LLVM_READONLY
Returns the maximum value for this type.
BlockCodeRegion - A region that represents code texts of blocks (closures).
The base class of the type hierarchy.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type.
MemRegion - The root abstract class for all memory regions.
const SymbolCast * getCastSymbol(const SymExpr *Operand, QualType From, QualType To)
AnalyzerOptions & getAnalyzerOptions() override
bool isReferenceType() const
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const SymbolicRegion * getSymbolicBase() const
If this is a symbolic region, returns the region.
const AnalyzerOptions & AnOpts
const SymbolDerived * getDerivedSymbol(SymbolRef parentSymbol, const TypedValueRegion *R)
virtual QualType getType() const =0
Represents a block literal declaration, which is like an unnamed FunctionDecl.
AnalysisDeclContext * getAnalysisDeclContext() const
DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedValueRegion *region)
Make a unique symbol for value of region.
ASTContext & getContext()
bool isNullPtrType() const
const BlockCodeRegion * getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy, AnalysisDeclContext *AC)
bool isFunctionPointerType() const
SVal ArrayToPointer(Loc Array, QualType ElementTy)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the 'this' object reference.
SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr)
SVal convertToArrayIndex(SVal val)
MemRegionManager & getRegionManager()
Value representing pointer-to-member.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
BlockDataRegion - A region that represents a block instance.
bool isFunctionType() const
bool UnwrapSimilarTypes(QualType &T1, QualType &T2, bool AllowPiMismatch=true)
Attempt to unwrap two types that may be similar (C++ [conv.qual]).
Optional< SVal > getConstantVal(const Expr *E)
Returns the value of E, if it can be determined in a non-path-sensitive manner.
EvalResult is a struct with detailed info about an evaluated expression.
BasicValueFactory & getBasicValueFactory()
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
uint32_t getBitWidth() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
static bool hasSameUnqualifiedPointeeType(QualType ty1, QualType ty2)
virtual SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op, Loc lhs, NonLoc rhs, QualType resultTy)=0
Create a new value which represents a binary expression with a memory location and non-location opera...
SymbolicRegion - A special, "non-concrete" region.
A record of the "type" of an APSInt, used for conversions.
and static some checkers Checker The latter are built on top of the former via the Checker and CheckerVisitor and attempts to isolate them from much of the gore of the internal analysis the analyzer is basically a source code simulator that traces out possible paths of execution The state of the and the combination of state and program point is a node in an exploded which has the entry program point and initial state
Optional< loc::MemRegionVal > getCastedMemRegionVal(const MemRegion *region, QualType type)
Return MemRegionVal on success cast, otherwise return None.
SVal makeSymExprValNN(BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, QualType resultTy)
Constructs a symbolic expression for two non-location values.
const SymbolMetadata * getMetadataSymbol(const MemRegion *R, const Stmt *S, QualType T, const LocationContext *LCtx, unsigned VisitCount, const void *SymbolTag=nullptr)
Creates a metadata symbol associated with a specific region.
Represents a C++ struct/union/class.
NonLoc makeCompoundVal(QualType type, llvm::ImmutableList< SVal > vals)
loc::MemRegionVal makeLoc(SymbolRef sym)
bool isMemberPointerType() const
const SymIntExpr * getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt &rhs, QualType t)
const SymbolRegionValue * getRegionValueSymbol(const TypedValueRegion *R)
Make a unique symbol for MemRegion R according to its kind.
StmtClass getStmtClass() const
bool isPointerType() const
static bool shouldBeModeledWithNoOp(ASTContext &Context, QualType ToTy, QualType FromTy)
Recursively check if the pointer types are equal modulo const, volatile, and restrict qualifiers.
SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy)
Cast a given SVal to another SVal using given QualType's.
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals)
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
void apply(llvm::APSInt &Value) const
Convert a given APSInt, in place, to match this type.
virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, QualType resultTy)=0
Create a new value which represents a binary expression with two non- location operands.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
FunctionCodeRegion - A region that represents code texts of function.
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
loc::ConcreteInt makeIntLocVal(const llvm::APSInt &integer)
Stores options for the analyzer from the command line.
DefinedSVal getFunctionPointer(const FunctionDecl *func)
Optional< const MemRegion * > castRegion(const MemRegion *region, QualType CastToTy)
castRegion - Used by ExprEngine::VisitCast to handle casts from a MemRegion* to a specific location t...
AnalysisManager & getAnalysisManager()
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy, const LocationContext *locContext, unsigned blockCount)
bool isBooleanType() const
const unsigned ArrayIndexWidth
The width of the scalar type used for array indices.
StoreManager & getStoreManager()
Represents symbolic expression that isn't a location.
nonloc::ConcreteInt makeTruthVal(bool b, QualType type)
ConditionTruthVal areEqual(ProgramStateRef state, SVal lhs, SVal rhs)
virtual QualType getValueType() const =0
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
bool isUnknownOrUndef() const
Stmt - This represents one statement.
SVal evalIntegralCast(ProgramStateRef state, SVal val, QualType castTy, QualType originalType)
BasicValueFactory BasicVals
Manager of APSInt values.
SVal evalCastSubKind(loc::ConcreteInt V, QualType CastTy, QualType OriginalTy)
const SymbolExtent * getExtentSymbol(const SubRegion *R)
nonloc::ConcreteInt makeBoolVal(const ObjCBoolLiteralExpr *boolean)
nonloc::SymbolVal simplifySymbolCast(nonloc::SymbolVal V, QualType CastTy)
Reduce cast expression by removing redundant intermediate casts.
SVal evalCastKind(UndefinedVal V, QualType CastTy, QualType OriginalTy)
SymbolManager SymMgr
Manages the creation of symbols.
const QualType ArrayIndexTy
The scalar type to use for array indices.
void removeCVRQualifiers(unsigned mask)
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
nonloc::SymbolVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt &rhs, QualType type)
TypedValueRegion - An abstract class representing regions having a typed value.
const SymbolicRegion * getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace=nullptr)
Retrieve or create a "symbolic" memory region.
SVal evalEQ(ProgramStateRef state, SVal lhs, SVal rhs)
This represents one expression.
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
QualType getConditionType() const
DefinedSVal getMemberPointer(const NamedDecl *ND)
Represents a function declaration or definition.
virtual SVal evalBinOpLL(ProgramStateRef state, BinaryOperator::Opcode op, Loc lhs, Loc rhs, QualType resultTy)=0
Create a new value which represents a binary expression with two memory location operands.
APSIntType getAPSIntType(QualType T) const
Returns the type of the APSInt used to store values of the given QualType.
const llvm::APSInt & getZeroWithTypeSize(QualType T)
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
static bool canSymbolicate(QualType T)
Represents a static or instance method of a struct/union/class.
MemRegionManager MemMgr
Manages the creation of memory regions.