31 const auto Name = CRD->
getName();
32 if (!(Name.ends_with_insensitive(
"iterator") ||
33 Name.ends_with_insensitive(
"iter") || Name.ends_with_insensitive(
"it")))
36 bool HasCopyCtor =
false, HasCopyAssign =
true, HasDtor =
false,
37 HasPreIncrOp =
false, HasPostIncrOp =
false, HasDerefOp =
false;
39 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(
Method)) {
40 if (Ctor->isCopyConstructor()) {
41 HasCopyCtor = !Ctor->isDeleted() && Ctor->getAccess() ==
AS_public;
45 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(
Method)) {
46 HasDtor = !Dtor->isDeleted() && Dtor->getAccess() ==
AS_public;
49 if (
Method->isCopyAssignmentOperator()) {
53 if (!
Method->isOverloadedOperator())
55 const auto OPK =
Method->getOverloadedOperator();
56 if (OPK == OO_PlusPlus) {
57 HasPreIncrOp = HasPreIncrOp || (
Method->getNumParams() == 0);
58 HasPostIncrOp = HasPostIncrOp || (
Method->getNumParams() == 1);
62 HasDerefOp = (
Method->getNumParams() == 0);
67 return HasCopyCtor && HasCopyAssign && HasDtor && HasPreIncrOp &&
68 HasPostIncrOp && HasDerefOp;
72 return OK == OO_EqualEqual || OK == OO_ExclaimEqual || OK == OO_Less ||
73 OK == OO_LessEqual || OK == OO_Greater || OK == OO_GreaterEqual;
77 const auto *IdInfo =
Func->getIdentifier();
80 if (
Func->getNumParams() < 2 ||
Func->getNumParams() > 3)
84 return IdInfo->getName() ==
"insert";
88 const auto *IdInfo =
Func->getIdentifier();
91 if (
Func->getNumParams() < 2)
95 return IdInfo->getName() ==
"emplace";
99 const auto *IdInfo =
Func->getIdentifier();
102 if (
Func->getNumParams() < 1 ||
Func->getNumParams() > 2)
106 if (
Func->getNumParams() == 2 &&
109 return IdInfo->getName() ==
"erase";
113 const auto *IdInfo =
Func->getIdentifier();
116 if (
Func->getNumParams() < 1 ||
Func->getNumParams() > 2)
120 if (
Func->getNumParams() == 2 &&
123 return IdInfo->getName() ==
"erase_after";
141 return OK == OO_Star || OK == OO_Arrow || OK == OO_ArrowStar ||
146 return OK == UO_Deref;
150 return OK == BO_PtrMemI;
154 return OK == OO_PlusPlus;
158 return OK == UO_PreInc || OK == UO_PostInc;
162 return OK == OO_MinusMinus;
166 return OK == UO_PreDec || OK == UO_PostDec;
170 return OK == OO_Plus || OK == OO_PlusEqual || OK == OO_Minus ||
175 return OK == BO_Add || OK == BO_AddAssign ||
176 OK == BO_Sub || OK == BO_SubAssign;
186 Reg = Reg->getMostDerivedObjectRegion();
199 Reg = Reg->getMostDerivedObjectRegion();
213 unsigned blockCount) {
214 auto &StateMgr = State->getStateManager();
215 auto &SymMgr = StateMgr.getSymbolManager();
216 auto &ACtx = StateMgr.getContext();
218 auto *Sym = SymMgr.conjureSymbol(Elem, LCtx, ACtx.LongTy, blockCount);
230 auto &SymMgr = State->getStateManager().getSymbolManager();
231 auto &SVB = State->getStateManager().getSValBuilder();
232 auto &BVF = State->getStateManager().getBasicVals();
234 assert ((Op == OO_Plus || Op == OO_PlusEqual ||
235 Op == OO_Minus || Op == OO_MinusEqual) &&
236 "Advance operator must be one of +, -, += and -=.");
237 auto BinOp = (Op == OO_Plus || Op == OO_PlusEqual) ? BO_Add : BO_Sub;
245 if (IntDist.
getValue()->isNegative()) {
247 BinOp = (BinOp == BO_Add) ? BO_Sub : BO_Add;
250 Pos->setTo(SVB.evalBinOp(State, BinOp,
252 IntDist, SymMgr.
getType(Pos->getOffset()))
270 assert(T->isSignedIntegerOrEnumerationType());
280 NewState = NewState->assume(*DV,
true);
290 NewState = NewState->assume(*DV,
true);
305 auto &SVB = State->getStateManager().getSValBuilder();
307 const auto comparison =
308 SVB.evalBinOp(State, Opc, NL1, NL2, SVB.getConditionType());
311 "Symbol comparison must be a `DefinedSVal`");
313 return !State->assume(comparison.castAs<
DefinedSVal>(),
false);
BinaryOperatorKind Opcode
Represents a C++ struct/union/class.
method_range methods() const
Represents a function declaration or definition.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
A (possibly-)qualified type.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs,...
A record of the "type" of an APSInt, used for conversions.
llvm::APSInt getMaxValue() const LLVM_READONLY
Returns the maximum value for this type.
llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY
APSIntType getAPSIntType(QualType T) const
Returns the type of the APSInt used to store values of the given QualType.
MemRegion - The root abstract class for all memory regions.
SValBuilder & getSValBuilder()
BasicValueFactory & getBasicValueFactory()
ProgramStateManager & getStateManager()
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.
QualType getConditionType() const
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
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.
QualType getType(const ASTContext &) const
Try to get a reasonable type for the given value.
const MemRegion * getAsRegion() const
virtual QualType getType() const =0
Value representing integer constant.
APSIntPtr getValue() const
While nonloc::CompoundVal covers a few simple use cases, nonloc::LazyCompoundVal is a more performant...
Represents symbolic expression that isn't a location.
ProgramStateRef createIteratorPosition(ProgramStateRef State, SVal Val, const MemRegion *Cont, ConstCFGElementRef Elem, const LocationContext *LCtx, unsigned blockCount)
bool isEraseCall(const FunctionDecl *Func)
const IteratorPosition * getIteratorPosition(ProgramStateRef State, SVal Val)
bool isIterator(const CXXRecordDecl *CRD)
bool isInsertCall(const FunctionDecl *Func)
bool isIteratorType(const QualType &Type)
bool isAccessOperator(OverloadedOperatorKind OK)
bool isEmplaceCall(const FunctionDecl *Func)
bool isEraseAfterCall(const FunctionDecl *Func)
ProgramStateRef assumeNoOverflow(ProgramStateRef State, SymbolRef Sym, long Scale)
bool isRandomIncrOrDecrOperator(OverloadedOperatorKind OK)
ProgramStateRef advancePosition(ProgramStateRef State, SVal Iter, OverloadedOperatorKind Op, SVal Distance)
const ContainerData * getContainerData(ProgramStateRef State, const MemRegion *Cont)
bool compare(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2, BinaryOperator::Opcode Opc)
bool isDecrementOperator(OverloadedOperatorKind OK)
bool isComparisonOperator(OverloadedOperatorKind OK)
ProgramStateRef setIteratorPosition(ProgramStateRef State, SVal Val, const IteratorPosition &Pos)
bool isDereferenceOperator(OverloadedOperatorKind OK)
bool isIncrementOperator(OverloadedOperatorKind OK)
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const SymExpr * SymbolRef
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
bool isa(CodeGen::Address addr)
CFGBlock::ConstCFGElementRef ConstCFGElementRef
static IteratorPosition getPosition(const MemRegion *C, SymbolRef Of)