37#include "llvm/ADT/APSInt.h"
38#include "llvm/Support/Compiler.h"
50void 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())
122 if (std::optional<nonloc::ConcreteInt> CI =
124 const llvm::APSInt& I = CI->getValue();
159 assert(Ex &&
"elem must be a CFGStmt containing an Expr");
179 if (
type->isNullPtrType())
196 unsigned visitCount) {
202 const void *symbolTag) {
211 const void *symbolTag) {
222 if (
type->isNullPtrType()) {
276 assert(!ND || (isa<CXXMethodDecl, FieldDecl, IndirectFieldDecl>(ND)));
278 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
284 if (!MD->isImplicitObjectMemberFunction())
298 unsigned blockCount) {
306std::optional<loc::MemRegionVal>
334 case Stmt::AddrLabelExprClass:
335 return makeLoc(cast<AddrLabelExpr>(
E));
337 case Stmt::CXXScalarValueInitExprClass:
338 case Stmt::ImplicitValueInitExprClass:
341 case Stmt::ObjCStringLiteralClass: {
342 const auto *SL = cast<ObjCStringLiteral>(
E);
346 case Stmt::StringLiteralClass: {
347 const auto *SL = cast<StringLiteral>(
E);
351 case Stmt::PredefinedExprClass: {
352 const auto *PE = cast<PredefinedExpr>(
E);
353 assert(PE->getFunctionName() &&
354 "Since we analyze only instantiated functions, PredefinedExpr "
355 "should have a function name.");
361 case Stmt::CharacterLiteralClass: {
362 const auto *
C = cast<CharacterLiteral>(
E);
366 case Stmt::CXXBoolLiteralExprClass:
369 case Stmt::TypeTraitExprClass: {
370 const auto *TE = cast<TypeTraitExpr>(
E);
371 if (TE->isStoredAsBoolean())
373 assert(TE->getAPValue().isInt() &&
"APValue type not supported");
377 case Stmt::IntegerLiteralClass:
380 case Stmt::ObjCBoolLiteralExprClass:
383 case Stmt::CXXNullPtrLiteralExprClass:
386 case Stmt::CStyleCastExprClass:
387 case Stmt::CXXFunctionalCastExprClass:
388 case Stmt::CXXConstCastExprClass:
389 case Stmt::CXXReinterpretCastExprClass:
390 case Stmt::CXXStaticCastExprClass:
391 case Stmt::ImplicitCastExprClass: {
392 const auto *CE = cast<CastExpr>(
E);
393 switch (CE->getCastKind()) {
396 case CK_ArrayToPointerDecay:
397 case CK_IntegralToPointer:
400 const Expr *SE = CE->getSubExpr();
438 const unsigned MaxComp =
AnOpts.MaxSymbolComplexity;
440 if (symLHS && symRHS &&
442 return makeNonLoc(symLHS, Op, symRHS, ResultTy);
445 if (std::optional<nonloc::ConcreteInt> rInt =
447 return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
450 if (std::optional<nonloc::ConcreteInt> lInt =
452 return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
458 switch (
X.getKind()) {
459 case nonloc::ConcreteIntKind:
461 case nonloc::SymbolValKind:
470 switch (
X.getKind()) {
471 case nonloc::ConcreteIntKind:
473 case nonloc::SymbolValKind:
491 llvm_unreachable(
"Unexpected unary operator");
502 if (isa<nonloc::LazyCompoundVal>(lhs) || isa<nonloc::LazyCompoundVal>(rhs)) {
506 if (op == BinaryOperatorKind::BO_Cmp) {
514 if (std::optional<Loc> LV = lhs.
getAs<
Loc>()) {
515 if (std::optional<Loc> RV = rhs.
getAs<
Loc>())
521 if (
const std::optional<Loc> RV = rhs.
getAs<
Loc>()) {
523 return Op == BO_Mul || Op == BO_Add || Op == BO_And || Op == BO_Xor ||
527 if (IsCommutative(op)) {
546 return state->isNonNull(
evalEQ(state, lhs, rhs));
556 return evalEQ(state,
static_cast<SVal>(lhs),
static_cast<SVal>(rhs))
574 if (Quals1 != Quals2)
600 return evalCast(val, castTy, originalTy);
604 if (!AsSymbol || !AsNonLoc)
605 return evalCast(val, castTy, originalTy);
620 std::tie(IsNotTruncated, IsTruncated) = state->assume(CompVal);
621 if (!IsNotTruncated && IsTruncated) {
623 return makeNonLoc(AsSymbol, originalTy, castTy);
625 return evalCast(val, castTy, originalTy);
634class EvalCastVisitor :
public SValVisitor<EvalCastVisitor, SVal> {
642 : VB(VB), Context(VB.getContext()), CastTy(CastTy),
643 OriginalTy(OriginalTy) {}
651 const bool IsUnknownOriginalType = OriginalTy.
isNull();
652 if (!IsUnknownOriginalType) {
655 if (CastTy == OriginalTy)
673 return VB.
makeTruthVal(
V.getValue()->getBoolValue(), CastTy);
677 llvm::APSInt
Value =
V.getValue();
684 llvm::APSInt
Value =
V.getValue();
700 const unsigned BitWidth = Context.
getIntWidth(CastTy);
704 const bool IsUnknownOriginalType = OriginalTy.
isNull();
705 if (!IsUnknownOriginalType) {
707 if (isa<ArrayType>(OriginalTy))
724 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FTR->getDecl()))
747 const bool IsUnknownOriginalType = OriginalTy.
isNull();
749 const auto *ArrayTy =
750 IsUnknownOriginalType
760 QualType ElemTy = ArrayTy->getElementType();
767 const unsigned BitWidth = Context.
getIntWidth(CastTy);
774 if (IsUnknownOriginalType) {
785 if (
const auto *SR = dyn_cast<SymbolicRegion>(R)) {
786 QualType SRTy = SR->getSymbol()->getType();
788 auto HasSameUnqualifiedPointeeType = [](
QualType ty1,
793 if (!HasSameUnqualifiedPointeeType(SRTy, CastTy)) {
801 if (
const auto *ER = dyn_cast<ElementRegion>(R)) {
820 QualType ElemTy = ArrayTy->getElementType();
869 auto CastedValue = [
V,
this]() {
870 llvm::APSInt
Value =
V.getValue();
877 return VB.
makeTruthVal(
V.getValue()->getBoolValue(), CastTy);
902 const bool IsUnknownOriginalType = OriginalTy.
isNull();
914 if (!IsUnknownOriginalType && R) {
929 if (IsUnknownOriginalType)
938 SE = SR->getSymbol();
944 const unsigned CastSize = Context.
getIntWidth(CastTy);
945 if (CastSize ==
V.getNumBits())
958 const bool IsUnknownOriginalType = OriginalTy.
isNull();
982 if (!Opts.ShouldSupportSymbolicIntegerCasts)
984 return simplifySymbolCast(
V, CastTy);
1057 if (!isa<SymbolCast>(SE))
1060 SymbolRef RootSym = cast<SymbolCast>(SE)->getOperand();
1075 const bool isSameType = (RT == CastTy);
1086 if (((WT > WR) && (UR || !UT)) || ((WT == WR) && (UT == UR)))
1106 EvalCastVisitor TRV{*
this, CastTy, OriginalTy};
1107 return TRV.Visit(
V);
Defines the clang::ASTContext interface.
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
llvm::DenseMap< const CFGBlock *, unsigned > VisitCount
static bool shouldBeModeledWithNoOp(ASTContext &Context, QualType ToTy, QualType FromTy)
Recursively check if the pointer types are equal modulo const, volatile, and restrict qualifiers.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
unsigned getIntWidth(QualType T) const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
bool UnwrapSimilarTypes(QualType &T1, QualType &T2, bool AllowPiMismatch=true) const
Attempt to unwrap two types that may be similar (C++ [conv.qual]).
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
ASTContext & getASTContext() const
Stores options for the analyzer from the command line.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
const Stmt * getStmt() const
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
This represents one expression.
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,...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
Represents a function declaration or definition.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
This represents a decl that may have a name.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getCanonicalType() const
The collection of all-type qualifiers we support.
void removeCVRQualifiers(unsigned mask)
It represents a stack frame of the call stack (based on CallEvent).
StmtClass getStmtClass() const
bool isBlockPointerType() const
bool isBooleanType() const
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
bool isVoidPointerType() const
bool isFunctionPointerType() const
bool isPointerType() const
bool isReferenceType() const
bool isVariableArrayType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isMemberPointerType() const
bool isFunctionType() const
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isNullPtrType() const
A safe wrapper around APSInt objects allocated and owned by BasicValueFactory.
A record of the "type" of an APSInt, used for conversions.
uint32_t getBitWidth() const
llvm::APSInt getMaxValue() const LLVM_READONLY
Returns the maximum value for this type.
void apply(llvm::APSInt &Value) const
Convert a given APSInt, in place, to match this type.
AllocaRegion - A region that represents an untyped blob of bytes created by a call to 'alloca'.
AnalyzerOptions & getAnalyzerOptions() override
APSIntPtr getZeroWithTypeSize(QualType T)
APSIntType getAPSIntType(QualType T) const
Returns the type of the APSInt used to store values of the given QualType.
llvm::ImmutableList< SVal > getEmptySValList()
Template implementation for all binary symbolic expressions.
BlockCodeRegion - A region that represents code texts of blocks (closures).
BlockDataRegion - A region that represents a block instance.
Represents an abstract call to a function or method along a particular path.
QualType getResultType() const
Returns the result type, adjusted for references.
const LocationContext * getLocationContext() const
The context in which the call is being evaluated.
const CFGBlock::ConstCFGElementRef & getCFGElementRef() const
AnalysisManager & getAnalysisManager()
FunctionCodeRegion - A region that represents code texts of function.
static bool isLocType(QualType T)
const BlockCodeRegion * getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy, AnalysisDeclContext *AC)
const AllocaRegion * getAllocaRegion(const Expr *Ex, unsigned Cnt, const LocationContext *LC)
getAllocaRegion - Retrieve a region associated with a call to alloca().
const SymbolicRegion * getSymbolicHeapRegion(SymbolRef sym)
Return a unique symbolic region belonging to heap memory space.
const SymbolicRegion * getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace=nullptr)
Retrieve or create a "symbolic" memory region.
const FunctionCodeRegion * getFunctionCodeRegion(const NamedDecl *FD)
const BlockDataRegion * getBlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc, unsigned blockCount)
getBlockDataRegion - Get the memory region associated with an instance of a block.
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
const SymbolicRegion * getSymbolicBase() const
If this is a symbolic region, returns the region.
ExprEngine & getOwningEngine()
SVal ArrayToPointer(Loc Array, QualType ElementTy)
StoreManager & getStoreManager()
DefinedSVal getConjuredHeapSymbolVal(ConstCFGElementRef elem, const LocationContext *LCtx, QualType type, unsigned Count)
Conjure a symbol representing heap allocated memory region.
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
DefinedSVal getMemberPointer(const NamedDecl *ND)
SVal evalMinus(NonLoc val)
SVal evalComplement(NonLoc val)
BasicValueFactory & getBasicValueFactory()
NonLoc makeCompoundVal(QualType type, llvm::ImmutableList< SVal > vals)
SymbolManager SymMgr
Manages the creation of symbols.
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...
DefinedSVal getMetadataSymbolVal(const void *symbolTag, const MemRegion *region, const Expr *expr, QualType type, const LocationContext *LCtx, unsigned count)
MemRegionManager & getRegionManager()
ProgramStateManager & getStateManager()
SVal makeSymExprValNN(BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, QualType resultTy)
Constructs a symbolic expression for two non-location values.
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.
const unsigned ArrayIndexWidth
The width of the scalar type used for array indices.
DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy, const LocationContext *locContext, unsigned blockCount)
DefinedSVal getFunctionPointer(const FunctionDecl *func)
const QualType ArrayIndexTy
The scalar type to use for array indices.
ASTContext & getContext()
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
SVal convertToArrayIndex(SVal val)
loc::MemRegionVal makeLoc(SymbolRef sym)
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.
SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy)
Cast a given SVal to another SVal using given QualType's.
BasicValueFactory BasicVals
Manager of APSInt values.
ConditionTruthVal areEqual(ProgramStateRef state, SVal lhs, SVal rhs)
QualType getConditionType() const
MemRegionManager MemMgr
Manages the creation of memory regions.
SVal evalEQ(ProgramStateRef state, SVal lhs, SVal rhs)
SVal evalUnaryOp(ProgramStateRef state, UnaryOperator::Opcode opc, SVal operand, QualType type)
DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, const TypedValueRegion *region)
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the 'this' object reference.
nonloc::ConcreteInt makeTruthVal(bool b, QualType type)
loc::ConcreteInt makeNullWithType(QualType type)
Create NULL pointer, with proper pointer bit-width for given address space.
ProgramStateManager & StateMgr
std::optional< SVal > getConstantVal(const Expr *E)
Returns the value of E, if it can be determined in a non-path-sensitive manner.
NonLoc makeLocAsInteger(Loc loc, unsigned bits)
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, ConstCFGElementRef elem, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
SVal evalIntegralCast(ProgramStateRef state, SVal val, QualType castTy, QualType originalType)
SymbolManager & getSymbolManager()
DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedValueRegion *region)
Make a unique symbol for value of region.
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type)
loc::ConcreteInt makeIntLocVal(const llvm::APSInt &integer)
nonloc::SymbolVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, APSIntPtr rhs, QualType type)
const AnalyzerOptions & AnOpts
std::optional< loc::MemRegionVal > getCastedMemRegionVal(const MemRegion *region, QualType type)
Return MemRegionVal on success cast, otherwise return std::nullopt.
loc::MemRegionVal getAllocaRegionVal(const Expr *E, const LocationContext *LCtx, unsigned Count)
Create an SVal representing the result of an alloca()-like call, that is, an AllocaRegion on the stac...
nonloc::ConcreteInt makeBoolVal(const ObjCBoolLiteralExpr *boolean)
SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr)
SValVisitor - this class implements a simple visitor for SVal subclasses.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
bool isUnknownOrUndef() const
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
const MemRegion * getAsRegion() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
std::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...
virtual QualType getType() const =0
virtual unsigned computeComplexity() const =0
Represents a cast expression.
A symbol representing the value of a MemRegion whose parent region has symbolic value.
SymbolExtent - Represents the extent (size in bytes) of a bounded region.
const SymExprT * acquire(Args &&...args)
Create or retrieve a SymExpr of type SymExprT for the given arguments.
const SymbolConjured * conjureSymbol(ConstCFGElementRef Elem, const LocationContext *LCtx, QualType T, unsigned VisitCount, const void *SymbolTag=nullptr)
static bool canSymbolicate(QualType T)
A symbol representing the value stored at a MemRegion.
SymbolicRegion - A special, "non-concrete" region.
TypedValueRegion - An abstract class representing regions having a typed value.
virtual QualType getValueType() const =0
Represents a symbolic expression involving a unary operator.
The simplest example of a concrete compound value is nonloc::CompoundVal, which represents a concrete...
Value representing integer constant.
APSIntPtr getValue() const
While nonloc::CompoundVal covers a few simple use cases, nonloc::LazyCompoundVal is a more performant...
Value representing pointer-to-member.
Represents symbolic expression that isn't a location.
LLVM_ATTRIBUTE_RETURNS_NONNULL SymbolRef getSymbol() const
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
The JSON file list parser is used to communicate input to InstallAPI.
CFGBlock::ConstCFGElementRef ConstCFGElementRef
@ Result
The result type of a method or function.
const FunctionProtoType * T
EvalResult is a struct with detailed info about an evaluated expression.