37#include "llvm/ADT/APSInt.h"
38#include "llvm/Support/Compiler.h"
50void SValBuilder::anchor() {}
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();
140 if (T->isNullPtrType())
159 assert(Ex &&
"elem must be a CFGStmt containing an Expr");
162 if (T->isNullPtrType())
179 if (
type->isNullPtrType())
196 unsigned visitCount) {
202 const void *symbolTag) {
211 const void *symbolTag) {
219 unsigned VisitCount) {
222 if (
type->isNullPtrType()) {
234 unsigned VisitCount) {
260 if (T->isNullPtrType())
277 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
283 if (!MD->isImplicitObjectMemberFunction())
297 unsigned blockCount) {
304std::optional<loc::MemRegionVal>
306 if (
auto OptR =
StateMgr.getStoreManager().castRegion(R, Ty))
332 case Stmt::AddrLabelExprClass:
335 case Stmt::CXXScalarValueInitExprClass:
336 case Stmt::ImplicitValueInitExprClass:
339 case Stmt::ObjCStringLiteralClass: {
344 case Stmt::StringLiteralClass: {
349 case Stmt::PredefinedExprClass: {
351 assert(PE->getFunctionName() &&
352 "Since we analyze only instantiated functions, PredefinedExpr "
353 "should have a function name.");
359 case Stmt::CharacterLiteralClass: {
364 case Stmt::CXXBoolLiteralExprClass:
367 case Stmt::TypeTraitExprClass: {
369 if (TE->isStoredAsBoolean())
371 assert(TE->getAPValue().isInt() &&
"APValue type not supported");
375 case Stmt::IntegerLiteralClass:
378 case Stmt::ObjCBoolLiteralExprClass:
381 case Stmt::CXXNullPtrLiteralExprClass:
384 case Stmt::CStyleCastExprClass:
385 case Stmt::CXXFunctionalCastExprClass:
386 case Stmt::CXXConstCastExprClass:
387 case Stmt::CXXReinterpretCastExprClass:
388 case Stmt::CXXStaticCastExprClass:
389 case Stmt::ImplicitCastExprClass: {
391 switch (CE->getCastKind()) {
394 case CK_ArrayToPointerDecay:
395 case CK_IntegralToPointer:
398 const Expr *SE = CE->getSubExpr();
436 const unsigned MaxComp =
AnOpts.MaxSymbolComplexity;
438 if (symLHS && symRHS &&
440 return makeNonLoc(symLHS, Op, symRHS, ResultTy);
443 if (std::optional<nonloc::ConcreteInt> rInt =
445 return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
448 if (std::optional<nonloc::ConcreteInt> lInt =
450 return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
456 switch (
X.getKind()) {
457 case nonloc::ConcreteIntKind:
459 case nonloc::SymbolValKind:
468 switch (
X.getKind()) {
469 case nonloc::ConcreteIntKind:
471 case nonloc::SymbolValKind:
489 llvm_unreachable(
"Unexpected unary operator");
504 if (op == BinaryOperatorKind::BO_Cmp) {
512 if (std::optional<Loc> LV = lhs.
getAs<
Loc>()) {
513 if (std::optional<Loc> RV = rhs.
getAs<
Loc>())
519 if (
const std::optional<Loc> RV = rhs.
getAs<
Loc>()) {
521 return Op == BO_Mul || Op == BO_Add || Op == BO_And || Op == BO_Xor ||
525 if (IsCommutative(op)) {
544 return state->isNonNull(
evalEQ(state, lhs, rhs));
554 return evalEQ(state,
static_cast<SVal>(lhs),
static_cast<SVal>(rhs))
563 while (Context.UnwrapSimilarTypes(ToTy, FromTy)) {
565 ToTy = Context.getUnqualifiedArrayType(ToTy, Quals1);
566 FromTy = Context.getUnqualifiedArrayType(FromTy, Quals2);
572 if (Quals1 != Quals2)
598 return evalCast(val, castTy, originalTy);
602 if (!AsSymbol || !AsNonLoc)
603 return evalCast(val, castTy, originalTy);
618 std::tie(IsNotTruncated, IsTruncated) = state->assume(CompVal);
619 if (!IsNotTruncated && IsTruncated) {
621 return makeNonLoc(AsSymbol, originalTy, castTy);
623 return evalCast(val, castTy, originalTy);
632class EvalCastVisitor :
public SValVisitor<EvalCastVisitor, SVal> {
640 : VB(VB), Context(VB.getContext()), CastTy(CastTy),
641 OriginalTy(OriginalTy) {}
649 const bool IsUnknownOriginalType = OriginalTy.
isNull();
650 if (!IsUnknownOriginalType) {
653 if (CastTy == OriginalTy)
661 Context.getPointerType(OriginalTy)))
666 SVal VisitUndefinedVal(UndefinedVal
V) {
return V; }
667 SVal VisitUnknownVal(UnknownVal
V) {
return V; }
668 SVal VisitConcreteInt(loc::ConcreteInt
V) {
671 return VB.
makeTruthVal(
V.getValue()->getBoolValue(), CastTy);
675 llvm::APSInt
Value =
V.getValue();
682 llvm::APSInt
Value =
V.getValue();
690 SVal VisitGotoLabel(loc::GotoLabel
V) {
698 const unsigned BitWidth = Context.
getIntWidth(CastTy);
702 const bool IsUnknownOriginalType = OriginalTy.
isNull();
703 if (!IsUnknownOriginalType) {
717 SVal VisitMemRegionVal(loc::MemRegionVal
V) {
720 const MemRegion *
R =
V.getRegion();
721 if (
const FunctionCodeRegion *FTR = dyn_cast<FunctionCodeRegion>(R))
722 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FTR->getDecl()))
727 return nonloc::SymbolVal(
730 if (
const SymbolicRegion *SymR =
R->getSymbolicBase()) {
745 const bool IsUnknownOriginalType = OriginalTy.
isNull();
747 const auto *ArrayTy =
748 IsUnknownOriginalType
758 QualType ElemTy = ArrayTy->getElementType();
765 const unsigned BitWidth = Context.
getIntWidth(CastTy);
772 if (IsUnknownOriginalType) {
781 const MemRegion *
R =
V.getRegion();
783 if (
const auto *SR = dyn_cast<SymbolicRegion>(R)) {
784 QualType SRTy = SR->getSymbol()->getType();
786 auto HasSameUnqualifiedPointeeType = [](QualType ty1,
791 if (!HasSameUnqualifiedPointeeType(SRTy, CastTy)) {
799 if (
const auto *ER = dyn_cast<ElementRegion>(R)) {
818 QualType ElemTy = ArrayTy->getElementType();
846 const MemRegion *
R =
V.getRegion();
862 SVal VisitCompoundVal(nonloc::CompoundVal
V) {
866 SVal VisitConcreteInt(nonloc::ConcreteInt
V) {
867 auto CastedValue = [
V,
this]() {
868 llvm::APSInt
Value =
V.getValue();
875 return VB.
makeTruthVal(
V.getValue()->getBoolValue(), CastTy);
888 SVal VisitLazyCompoundVal(nonloc::LazyCompoundVal
V) {
892 SVal VisitLocAsInteger(nonloc::LocAsInteger
V) {
900 const bool IsUnknownOriginalType = OriginalTy.
isNull();
912 if (!IsUnknownOriginalType && R) {
914 return VisitMemRegionVal(loc::MemRegionVal(R));
927 if (IsUnknownOriginalType)
928 return VisitMemRegionVal(loc::MemRegionVal(R));
934 if (
const SymbolicRegion *SR =
935 dyn_cast<SymbolicRegion>(
R->StripCasts())) {
936 SE = SR->getSymbol();
942 const unsigned CastSize = Context.
getIntWidth(CastTy);
943 if (CastSize ==
V.getNumBits())
953 SVal VisitSymbolVal(nonloc::SymbolVal
V) {
956 const bool IsUnknownOriginalType = OriginalTy.
isNull();
980 if (!Opts.ShouldSupportSymbolicIntegerCasts)
982 return simplifySymbolCast(
V, CastTy);
998 SVal VisitPointerToMember(nonloc::PointerToMember
V) {
1013 nonloc::SymbolVal simplifySymbolCast(nonloc::SymbolVal
V, QualType CastTy) {
1073 const bool isSameType = (RT == CastTy);
1075 return nonloc::SymbolVal(RootSym);
1084 if (((WT > WR) && (UR || !UT)) || ((WT == WR) && (UT == UR)))
1104 EvalCastVisitor TRV{*
this, CastTy, OriginalTy};
1105 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.
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
static CanQualType getCanonicalType(QualType T)
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.
ASTContext & getASTContext() const
BinaryOperatorKind Opcode
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.
QualType getThisType() const
Return the type of the this pointer.
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.
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.
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
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...
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.
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 StackFrame * getStackFrame() const
The stack frame in which the call is being evaluated.
const CFGBlock::ConstCFGElementRef & getCFGElementRef() const
AnalysisManager & getAnalysisManager()
static bool isLocType(QualType T)
const AllocaRegion * getAllocaRegion(const Expr *Ex, unsigned Cnt, const StackFrame *SF)
getAllocaRegion - Retrieve a region associated with a call to alloca().
MemRegion - The root abstract class for all memory regions.
ExprEngine & getOwningEngine()
SVal ArrayToPointer(Loc Array, QualType ElementTy)
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...
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 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)
DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy, const StackFrame *SF, unsigned blockCount)
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.
const AnalyzerOptions & getAnalyzerOptions() const
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)
nonloc::ConcreteInt makeTruthVal(bool b, QualType type)
loc::ConcreteInt makeNullWithType(QualType type)
Create NULL pointer, with proper pointer bit-width for given address space.
loc::MemRegionVal getAllocaRegionVal(const Expr *E, const StackFrame *SF, unsigned Count)
Create an SVal representing the result of an alloca()-like call, that is, an AllocaRegion on the stac...
ProgramStateManager & StateMgr
DefinedSVal getConjuredHeapSymbolVal(ConstCFGElementRef elem, const StackFrame *SF, QualType type, unsigned Count)
Conjure a symbol representing heap allocated memory region.
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.
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrame *SF)
Return a memory region for the 'this' object reference.
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type)
loc::ConcreteInt makeIntLocVal(const llvm::APSInt &integer)
DefinedSVal getMetadataSymbolVal(const void *symbolTag, const MemRegion *region, const Expr *expr, QualType type, const StackFrame *SF, unsigned count)
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, ConstCFGElementRef elem, const StackFrame *SF, unsigned count)
Create a new symbol with a unique 'name'.
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.
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.
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.
const SymExprT * acquire(Args &&...args)
Create or retrieve a SymExpr of type SymExprT for the given arguments.
static bool canSymbolicate(QualType T)
A symbol representing the value stored at a MemRegion.
TypedValueRegion - An abstract class representing regions having a typed value.
virtual QualType getValueType() const =0
Represents a symbolic expression involving a unary operator.
Value representing integer constant.
APSIntPtr getValue() const
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.
BinarySymExprImpl< APSIntPtr, const SymExpr *, SymExpr::Kind::IntSymExprKind > IntSymExpr
Represents a symbolic expression like 3 - 'x'.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const SymExpr * SymbolRef
BinarySymExprImpl< const SymExpr *, const SymExpr *, SymExpr::Kind::SymSymExprKind > SymSymExpr
Represents a symbolic expression like 'x' + 'y'.
BinarySymExprImpl< const SymExpr *, APSIntPtr, SymExpr::Kind::SymIntExprKind > SymIntExpr
Represents a symbolic expression like 'x' + 3.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
CFGBlock::ConstCFGElementRef ConstCFGElementRef
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Result
The result type of a method or function.
U cast(CodeGen::Address addr)
EvalResult is a struct with detailed info about an evaluated expression.