31 const auto Name = CRD->
getName();
32 if (!(Name.endswith_lower(
"iterator") || Name.endswith_lower(
"iter") ||
33 Name.endswith_lower(
"it")))
36 bool HasCopyCtor =
false, HasCopyAssign =
true, HasDtor =
false,
37 HasPreIncrOp =
false, HasPostIncrOp =
false, HasDerefOp =
false;
38 for (
const auto *Method : CRD->
methods()) {
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()) {
50 HasCopyAssign = !Method->isDeleted() && Method->getAccess() ==
AS_public;
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;
84 return IdInfo->
getName() ==
"insert";
95 return IdInfo->
getName() ==
"emplace";
109 return IdInfo->
getName() ==
"erase";
123 return IdInfo->
getName() ==
"erase_after";
132 return OK == OO_Star || OK == OO_Arrow || OK == OO_ArrowStar ||
137 return OK == OO_PlusPlus;
141 return OK == OO_MinusMinus;
145 return OK == OO_Plus || OK == OO_PlusEqual || OK == OO_Minus ||
157 Reg = Reg->getMostDerivedObjectRegion();
170 Reg = Reg->getMostDerivedObjectRegion();
182 const SVal &Distance) {
187 auto &SymMgr = State->getStateManager().getSymbolManager();
188 auto &SVB = State->getStateManager().getSValBuilder();
190 assert ((Op == OO_Plus || Op == OO_PlusEqual ||
191 Op == OO_Minus || Op == OO_MinusEqual) &&
192 "Advance operator must be one of +, -, += and -=.");
193 auto BinOp = (Op == OO_Plus || Op == OO_PlusEqual) ? BO_Add : BO_Sub;
197 Pos->setTo(SVB.evalBinOp(State, BinOp,
199 *IntDist, SymMgr.getType(Pos->getOffset()))
214 auto &SVB = State->getStateManager().getSValBuilder();
216 const auto comparison =
217 SVB.evalBinOp(State, Opc, NL1, NL2, SVB.getConditionType());
220 "Symbol comparison must be a `DefinedSVal`");
222 return !State->assume(comparison.castAs<
DefinedSVal>(),
false);
bool isDecrementOperator(OverloadedOperatorKind OK)
Represents a function declaration or definition.
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
The base class of the type hierarchy.
Value representing integer constant.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
bool isComparisonOperator(OverloadedOperatorKind OK)
bool isIteratorType(const QualType &Type)
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs, typeofs, etc., as well as any qualifiers.
bool isIncrementOperator(OverloadedOperatorKind OK)
const IteratorPosition * getIteratorPosition(ProgramStateRef State, const SVal &Val)
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const ContainerData * getContainerData(ProgramStateRef State, const MemRegion *Cont)
bool isIterator(const CXXRecordDecl *CRD)
bool isEraseCall(const FunctionDecl *Func)
bool isDereferenceOperator(OverloadedOperatorKind OK)
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
const MemRegion * getAsRegion() const
const ParmVarDecl * getParamDecl(unsigned i) const
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
bool isAccessOperator(OverloadedOperatorKind OK)
StringRef getName() const
Return the actual identifier string.
bool isEraseAfterCall(const FunctionDecl *Func)
Dataflow Directional Tag Classes.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
bool isRandomIncrOrDecrOperator(OverloadedOperatorKind OK)
Represents symbolic expression that isn't a location.
bool isInsertCall(const FunctionDecl *Func)
ProgramStateRef advancePosition(ProgramStateRef State, const SVal &Iter, OverloadedOperatorKind Op, const SVal &Distance)
Represents a C++ struct/union/class.
bool isEmplaceCall(const FunctionDecl *Func)
ProgramStateRef setIteratorPosition(ProgramStateRef State, const SVal &Val, const IteratorPosition &Pos)
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
bool compare(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2, BinaryOperator::Opcode Opc)
bool isPointerType() const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
method_range methods() const