36#include "llvm/ADT/APSInt.h"
37#include "llvm/Support/Casting.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())
79 const llvm::APSInt &rhs,
126 if (std::optional<nonloc::ConcreteInt> CI =
128 const llvm::APSInt& I = CI->getValue();
181 if (
type->isNullPtrType())
198 unsigned visitCount) {
199 if (
type->isNullPtrType())
227 if (
type->isNullPtrType())
278 assert(!ND || (isa<CXXMethodDecl, FieldDecl, IndirectFieldDecl>(ND)));
280 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
286 if (!MD->isImplicitObjectMemberFunction())
300 unsigned blockCount) {
308std::optional<loc::MemRegionVal>
325 const Type *
T =
D->getTypeForDecl();
336 case Stmt::AddrLabelExprClass:
337 return makeLoc(cast<AddrLabelExpr>(
E));
339 case Stmt::CXXScalarValueInitExprClass:
340 case Stmt::ImplicitValueInitExprClass:
343 case Stmt::ObjCStringLiteralClass: {
344 const auto *SL = cast<ObjCStringLiteral>(
E);
348 case Stmt::StringLiteralClass: {
349 const auto *SL = cast<StringLiteral>(
E);
353 case Stmt::PredefinedExprClass: {
354 const auto *PE = cast<PredefinedExpr>(
E);
355 assert(PE->getFunctionName() &&
356 "Since we analyze only instantiated functions, PredefinedExpr "
357 "should have a function name.");
363 case Stmt::CharacterLiteralClass: {
364 const auto *
C = cast<CharacterLiteral>(
E);
368 case Stmt::CXXBoolLiteralExprClass:
371 case Stmt::TypeTraitExprClass: {
372 const auto *TE = cast<TypeTraitExpr>(
E);
376 case Stmt::IntegerLiteralClass:
379 case Stmt::ObjCBoolLiteralExprClass:
382 case Stmt::CXXNullPtrLiteralExprClass:
385 case Stmt::CStyleCastExprClass:
386 case Stmt::CXXFunctionalCastExprClass:
387 case Stmt::CXXConstCastExprClass:
388 case Stmt::CXXReinterpretCastExprClass:
389 case Stmt::CXXStaticCastExprClass:
390 case Stmt::ImplicitCastExprClass: {
391 const auto *CE = cast<CastExpr>(
E);
392 switch (CE->getCastKind()) {
395 case CK_ArrayToPointerDecay:
396 case CK_IntegralToPointer:
399 const Expr *SE = CE->getSubExpr();
437 const unsigned MaxComp =
AnOpts.MaxSymbolComplexity;
439 if (symLHS && symRHS &&
441 return makeNonLoc(symLHS, Op, symRHS, ResultTy);
444 if (std::optional<nonloc::ConcreteInt> rInt =
446 return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
449 if (std::optional<nonloc::ConcreteInt> lInt =
451 return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
457 switch (
X.getKind()) {
458 case nonloc::ConcreteIntKind:
460 case nonloc::SymbolValKind:
469 switch (
X.getKind()) {
470 case nonloc::ConcreteIntKind:
472 case nonloc::SymbolValKind:
490 llvm_unreachable(
"Unexpected unary operator");
501 if (isa<nonloc::LazyCompoundVal>(lhs) || isa<nonloc::LazyCompoundVal>(rhs)) {
505 if (op == BinaryOperatorKind::BO_Cmp) {
513 if (std::optional<Loc> LV = lhs.
getAs<
Loc>()) {
514 if (std::optional<Loc> RV = rhs.
getAs<
Loc>())
520 if (
const std::optional<Loc> RV = rhs.
getAs<
Loc>()) {
522 return Op == BO_Mul || Op == BO_Add || Op == BO_And || Op == BO_Xor ||
526 if (IsCommutative(op)) {
545 return state->isNonNull(
evalEQ(state, lhs, rhs));
555 return evalEQ(state,
static_cast<SVal>(lhs),
static_cast<SVal>(rhs))
573 if (Quals1 != Quals2)
599 return evalCast(val, castTy, originalTy);
603 return evalCast(val, castTy, originalTy);
619 std::tie(IsNotTruncated, IsTruncated) = state->assume(CompVal);
620 if (!IsNotTruncated && IsTruncated) {
624 return evalCast(val, castTy, originalTy);
633class EvalCastVisitor :
public SValVisitor<EvalCastVisitor, SVal> {
641 : VB(VB), Context(VB.getContext()), CastTy(CastTy),
642 OriginalTy(OriginalTy) {}
650 const bool IsUnknownOriginalType = OriginalTy.
isNull();
651 if (!IsUnknownOriginalType) {
654 if (CastTy == OriginalTy)
676 llvm::APSInt
Value =
V.getValue();
683 llvm::APSInt
Value =
V.getValue();
699 const unsigned BitWidth = Context.
getIntWidth(CastTy);
703 const bool IsUnknownOriginalType = OriginalTy.
isNull();
704 if (!IsUnknownOriginalType) {
706 if (isa<ArrayType>(OriginalTy))
723 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FTR->getDecl()))
746 const bool IsUnknownOriginalType = OriginalTy.
isNull();
748 const auto *ArrayTy =
749 IsUnknownOriginalType
759 QualType ElemTy = ArrayTy->getElementType();
766 const unsigned BitWidth = Context.
getIntWidth(CastTy);
773 if (IsUnknownOriginalType) {
784 if (
const auto *SR = dyn_cast<SymbolicRegion>(R)) {
785 QualType SRTy = SR->getSymbol()->getType();
787 auto HasSameUnqualifiedPointeeType = [](
QualType ty1,
792 if (!HasSameUnqualifiedPointeeType(SRTy, CastTy)) {
800 if (
const auto *ER = dyn_cast<ElementRegion>(R)) {
819 QualType ElemTy = ArrayTy->getElementType();
868 auto CastedValue = [
V,
this]() {
869 llvm::APSInt
Value =
V.getValue();
901 const bool IsUnknownOriginalType = OriginalTy.
isNull();
913 if (!IsUnknownOriginalType && R) {
928 if (IsUnknownOriginalType)
937 SE = SR->getSymbol();
943 const unsigned CastSize = Context.
getIntWidth(CastTy);
944 if (CastSize ==
V.getNumBits())
957 const bool IsUnknownOriginalType = OriginalTy.
isNull();
981 if (!Opts.ShouldSupportSymbolicIntegerCasts)
983 return simplifySymbolCast(
V, CastTy);
1056 if (!isa<SymbolCast>(SE))
1059 SymbolRef RootSym = cast<SymbolCast>(SE)->getOperand();
1074 const bool isSameType = (RT == CastTy);
1085 if (((WT > WR) && (UR || !UT)) || ((WT == WR) && (UT == UR)))
1105 EvalCastVisitor TRV{*
this, CastTy, OriginalTy};
1106 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)
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.
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).
Stmt - This represents one statement.
StmtClass getStmtClass() const
The base class of the type hierarchy.
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 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
APSIntType getAPSIntType(QualType T) const
Returns the type of the APSInt used to store values of the given QualType.
llvm::ImmutableList< SVal > getEmptySValList()
const llvm::APSInt & getZeroWithTypeSize(QualType T)
BlockCodeRegion - A region that represents code texts of blocks (closures).
BlockDataRegion - A region that represents a block instance.
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()
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.
nonloc::SymbolVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt &rhs, QualType type)
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.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
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)
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)
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)
DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E, const LocationContext *LCtx, unsigned Count)
Conjure a symbol representing heap allocated memory region.
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
const SymbolExtent * getExtentSymbol(const SubRegion *R)
const SymbolDerived * getDerivedSymbol(SymbolRef parentSymbol, const TypedValueRegion *R)
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.
const SymbolRegionValue * getRegionValueSymbol(const TypedValueRegion *R)
Make a unique symbol for MemRegion R according to its kind.
const SymbolConjured * conjureSymbol(const Stmt *E, const LocationContext *LCtx, QualType T, unsigned VisitCount, const void *SymbolTag=nullptr)
const SymIntExpr * getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt &rhs, QualType t)
const SymbolCast * getCastSymbol(const SymExpr *Operand, QualType From, QualType To)
const UnarySymExpr * getUnarySymExpr(const SymExpr *operand, UnaryOperator::Opcode op, QualType t)
static bool canSymbolicate(QualType T)
const SymSymExpr * getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t)
const IntSymExpr * getIntSymExpr(const llvm::APSInt &lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t)
SymbolicRegion - A special, "non-concrete" region.
TypedValueRegion - An abstract class representing regions having a typed value.
virtual QualType getValueType() const =0
The simplest example of a concrete compound value is nonloc::CompoundVal, which represents a concrete...
Value representing integer constant.
const llvm::APSInt & 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::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
const FunctionProtoType * T
EvalResult is a struct with detailed info about an evaluated expression.