003 File Manager
Current Path:
/usr/src/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers
usr
/
src
/
contrib
/
llvm-project
/
clang
/
lib
/
StaticAnalyzer
/
Checkers
/
📁
..
📄
AllocationState.h
(1.41 KB)
📄
AnalysisOrderChecker.cpp
(8.62 KB)
📄
AnalyzerStatsChecker.cpp
(5.04 KB)
📄
ArrayBoundChecker.cpp
(3.22 KB)
📄
ArrayBoundCheckerV2.cpp
(13.07 KB)
📄
BasicObjCFoundationChecks.cpp
(43.82 KB)
📄
BlockInCriticalSectionChecker.cpp
(6.69 KB)
📄
BoolAssignmentChecker.cpp
(3.45 KB)
📄
BuiltinFunctionChecker.cpp
(5 KB)
📄
CStringChecker.cpp
(93.24 KB)
📄
CStringSyntaxChecker.cpp
(9.8 KB)
📄
CXXSelfAssignmentChecker.cpp
(3.08 KB)
📄
CallAndMessageChecker.cpp
(26.57 KB)
📄
CastSizeChecker.cpp
(4.96 KB)
📄
CastToStructChecker.cpp
(4.43 KB)
📄
CastValueChecker.cpp
(19.65 KB)
📄
CheckObjCDealloc.cpp
(37.83 KB)
📄
CheckObjCInstMethSignature.cpp
(4.8 KB)
📄
CheckPlacementNew.cpp
(11.91 KB)
📄
CheckSecuritySyntaxOnly.cpp
(38.79 KB)
📄
CheckSizeofPointer.cpp
(3.16 KB)
📄
CheckerDocumentation.cpp
(14.64 KB)
📄
ChrootChecker.cpp
(4.88 KB)
📄
CloneChecker.cpp
(8.28 KB)
📄
ContainerModeling.cpp
(39.85 KB)
📄
ConversionChecker.cpp
(7.11 KB)
📄
DeadStoresChecker.cpp
(17.82 KB)
📄
DebugCheckers.cpp
(10.41 KB)
📄
DebugContainerModeling.cpp
(4.94 KB)
📄
DebugIteratorModeling.cpp
(5.15 KB)
📄
DeleteWithNonVirtualDtorChecker.cpp
(5.35 KB)
📄
DereferenceChecker.cpp
(10.54 KB)
📄
DirectIvarAssignment.cpp
(8.02 KB)
📄
DivZeroChecker.cpp
(3.42 KB)
📄
DynamicTypeChecker.cpp
(7.31 KB)
📄
DynamicTypePropagation.cpp
(42.11 KB)
📄
EnumCastOutOfRangeChecker.cpp
(5.75 KB)
📄
ExprInspectionChecker.cpp
(15.6 KB)
📄
FixedAddressChecker.cpp
(2.33 KB)
📄
FuchsiaHandleChecker.cpp
(23.1 KB)
📄
GCDAntipatternChecker.cpp
(7.85 KB)
📄
GTestChecker.cpp
(10.52 KB)
📄
GenericTaintChecker.cpp
(34.31 KB)
📄
IdenticalExprChecker.cpp
(18.88 KB)
📄
InnerPointerChecker.cpp
(11.54 KB)
📄
InterCheckerAPI.h
(1.09 KB)
📄
InvalidatedIteratorChecker.cpp
(4.93 KB)
📄
Iterator.cpp
(10.62 KB)
📄
Iterator.h
(6.32 KB)
📄
IteratorModeling.cpp
(31.33 KB)
📄
IteratorRangeChecker.cpp
(12.64 KB)
📄
IvarInvalidationChecker.cpp
(27.63 KB)
📄
LLVMConventionsChecker.cpp
(9.9 KB)
📄
LocalizationChecker.cpp
(52.38 KB)
📄
MIGChecker.cpp
(11.3 KB)
📁
MPI-Checker
📄
MacOSKeychainAPIChecker.cpp
(25.21 KB)
📄
MacOSXAPIChecker.cpp
(6.61 KB)
📄
MallocChecker.cpp
(127.38 KB)
📄
MallocOverflowSecurityChecker.cpp
(11.91 KB)
📄
MallocSizeofChecker.cpp
(8.03 KB)
📄
MismatchedIteratorChecker.cpp
(11.01 KB)
📄
MmapWriteExecChecker.cpp
(3.22 KB)
📄
Move.h
(1.07 KB)
📄
MoveChecker.cpp
(27 KB)
📄
NSAutoreleasePoolChecker.cpp
(2.93 KB)
📄
NSErrorChecker.cpp
(10.6 KB)
📄
NoReturnFunctionChecker.cpp
(5.48 KB)
📄
NonNullParamChecker.cpp
(11.22 KB)
📄
NonnullGlobalConstantsChecker.cpp
(5.09 KB)
📄
NullabilityChecker.cpp
(46.95 KB)
📄
NumberObjectConversionChecker.cpp
(13.69 KB)
📄
OSObjectCStyleCast.cpp
(3.14 KB)
📄
ObjCAtSyncChecker.cpp
(3.34 KB)
📄
ObjCAutoreleaseWriteChecker.cpp
(8.62 KB)
📄
ObjCContainersASTChecker.cpp
(5.5 KB)
📄
ObjCContainersChecker.cpp
(6.71 KB)
📄
ObjCMissingSuperCallChecker.cpp
(9.23 KB)
📄
ObjCPropertyChecker.cpp
(3.03 KB)
📄
ObjCSelfInitChecker.cpp
(16.21 KB)
📄
ObjCSuperDeallocChecker.cpp
(9.33 KB)
📄
ObjCUnusedIVarsChecker.cpp
(6.01 KB)
📄
PaddingChecker.cpp
(14.26 KB)
📄
PointerArithChecker.cpp
(12.18 KB)
📄
PointerIterationChecker.cpp
(3.79 KB)
📄
PointerSortingChecker.cpp
(4.5 KB)
📄
PointerSubChecker.cpp
(2.56 KB)
📄
PthreadLockChecker.cpp
(28.42 KB)
📁
RetainCountChecker
📄
ReturnPointerRangeChecker.cpp
(3.39 KB)
📄
ReturnUndefChecker.cpp
(4.1 KB)
📄
ReturnValueChecker.cpp
(5.79 KB)
📄
RunLoopAutoreleaseLeakChecker.cpp
(7.2 KB)
📄
STLAlgorithmModeling.cpp
(7 KB)
📄
SimpleStreamChecker.cpp
(9.43 KB)
📄
SmartPtr.h
(1.17 KB)
📄
SmartPtrChecker.cpp
(2.68 KB)
📄
SmartPtrModeling.cpp
(8.05 KB)
📄
StackAddrEscapeChecker.cpp
(15 KB)
📄
StdLibraryFunctionsChecker.cpp
(74.86 KB)
📄
StreamChecker.cpp
(37.36 KB)
📄
Taint.cpp
(9.04 KB)
📄
Taint.h
(4.19 KB)
📄
TaintTesterChecker.cpp
(2.17 KB)
📄
TestAfterDivZeroChecker.cpp
(8.19 KB)
📄
TraversalChecker.cpp
(4.38 KB)
📄
TrustNonnullChecker.cpp
(9.12 KB)
📄
UndefBranchChecker.cpp
(3.82 KB)
📄
UndefCapturedBlockVarChecker.cpp
(3.64 KB)
📄
UndefResultChecker.cpp
(7.19 KB)
📄
UndefinedArraySubscriptChecker.cpp
(2.36 KB)
📄
UndefinedAssignmentChecker.cpp
(3.74 KB)
📁
UninitializedObject
📄
UnixAPIChecker.cpp
(18.05 KB)
📄
UnreachableCodeChecker.cpp
(9.59 KB)
📄
VLASizeChecker.cpp
(10.95 KB)
📄
ValistChecker.cpp
(15.65 KB)
📄
VforkChecker.cpp
(7.67 KB)
📄
VirtualCallChecker.cpp
(8.11 KB)
📁
WebKit
📄
Yaml.h
(2.06 KB)
📁
cert
Editing: Iterator.cpp
//=== Iterator.cpp - Common functions for iterator checkers. -------*- C++ -*-// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Defines common functions to be used by the itertor checkers . // //===----------------------------------------------------------------------===// #include "Iterator.h" namespace clang { namespace ento { namespace iterator { bool isIteratorType(const QualType &Type) { if (Type->isPointerType()) return true; const auto *CRD = Type->getUnqualifiedDesugaredType()->getAsCXXRecordDecl(); return isIterator(CRD); } bool isIterator(const CXXRecordDecl *CRD) { if (!CRD) return false; const auto Name = CRD->getName(); if (!(Name.endswith_lower("iterator") || Name.endswith_lower("iter") || Name.endswith_lower("it"))) return false; bool HasCopyCtor = false, HasCopyAssign = true, HasDtor = false, HasPreIncrOp = false, HasPostIncrOp = false, HasDerefOp = false; for (const auto *Method : CRD->methods()) { if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(Method)) { if (Ctor->isCopyConstructor()) { HasCopyCtor = !Ctor->isDeleted() && Ctor->getAccess() == AS_public; } continue; } if (const auto *Dtor = dyn_cast<CXXDestructorDecl>(Method)) { HasDtor = !Dtor->isDeleted() && Dtor->getAccess() == AS_public; continue; } if (Method->isCopyAssignmentOperator()) { HasCopyAssign = !Method->isDeleted() && Method->getAccess() == AS_public; continue; } if (!Method->isOverloadedOperator()) continue; const auto OPK = Method->getOverloadedOperator(); if (OPK == OO_PlusPlus) { HasPreIncrOp = HasPreIncrOp || (Method->getNumParams() == 0); HasPostIncrOp = HasPostIncrOp || (Method->getNumParams() == 1); continue; } if (OPK == OO_Star) { HasDerefOp = (Method->getNumParams() == 0); continue; } } return HasCopyCtor && HasCopyAssign && HasDtor && HasPreIncrOp && HasPostIncrOp && HasDerefOp; } bool isComparisonOperator(OverloadedOperatorKind OK) { return OK == OO_EqualEqual || OK == OO_ExclaimEqual || OK == OO_Less || OK == OO_LessEqual || OK == OO_Greater || OK == OO_GreaterEqual; } bool isInsertCall(const FunctionDecl *Func) { const auto *IdInfo = Func->getIdentifier(); if (!IdInfo) return false; if (Func->getNumParams() < 2 || Func->getNumParams() > 3) return false; if (!isIteratorType(Func->getParamDecl(0)->getType())) return false; return IdInfo->getName() == "insert"; } bool isEmplaceCall(const FunctionDecl *Func) { const auto *IdInfo = Func->getIdentifier(); if (!IdInfo) return false; if (Func->getNumParams() < 2) return false; if (!isIteratorType(Func->getParamDecl(0)->getType())) return false; return IdInfo->getName() == "emplace"; } bool isEraseCall(const FunctionDecl *Func) { const auto *IdInfo = Func->getIdentifier(); if (!IdInfo) return false; if (Func->getNumParams() < 1 || Func->getNumParams() > 2) return false; if (!isIteratorType(Func->getParamDecl(0)->getType())) return false; if (Func->getNumParams() == 2 && !isIteratorType(Func->getParamDecl(1)->getType())) return false; return IdInfo->getName() == "erase"; } bool isEraseAfterCall(const FunctionDecl *Func) { const auto *IdInfo = Func->getIdentifier(); if (!IdInfo) return false; if (Func->getNumParams() < 1 || Func->getNumParams() > 2) return false; if (!isIteratorType(Func->getParamDecl(0)->getType())) return false; if (Func->getNumParams() == 2 && !isIteratorType(Func->getParamDecl(1)->getType())) return false; return IdInfo->getName() == "erase_after"; } bool isAccessOperator(OverloadedOperatorKind OK) { return isDereferenceOperator(OK) || isIncrementOperator(OK) || isDecrementOperator(OK) || isRandomIncrOrDecrOperator(OK); } bool isAccessOperator(UnaryOperatorKind OK) { return isDereferenceOperator(OK) || isIncrementOperator(OK) || isDecrementOperator(OK); } bool isAccessOperator(BinaryOperatorKind OK) { return isDereferenceOperator(OK) || isRandomIncrOrDecrOperator(OK); } bool isDereferenceOperator(OverloadedOperatorKind OK) { return OK == OO_Star || OK == OO_Arrow || OK == OO_ArrowStar || OK == OO_Subscript; } bool isDereferenceOperator(UnaryOperatorKind OK) { return OK == UO_Deref; } bool isDereferenceOperator(BinaryOperatorKind OK) { return OK == BO_PtrMemI; } bool isIncrementOperator(OverloadedOperatorKind OK) { return OK == OO_PlusPlus; } bool isIncrementOperator(UnaryOperatorKind OK) { return OK == UO_PreInc || OK == UO_PostInc; } bool isDecrementOperator(OverloadedOperatorKind OK) { return OK == OO_MinusMinus; } bool isDecrementOperator(UnaryOperatorKind OK) { return OK == UO_PreDec || OK == UO_PostDec; } bool isRandomIncrOrDecrOperator(OverloadedOperatorKind OK) { return OK == OO_Plus || OK == OO_PlusEqual || OK == OO_Minus || OK == OO_MinusEqual; } bool isRandomIncrOrDecrOperator(BinaryOperatorKind OK) { return OK == BO_Add || OK == BO_AddAssign || OK == BO_Sub || OK == BO_SubAssign; } const ContainerData *getContainerData(ProgramStateRef State, const MemRegion *Cont) { return State->get<ContainerMap>(Cont); } const IteratorPosition *getIteratorPosition(ProgramStateRef State, const SVal &Val) { if (auto Reg = Val.getAsRegion()) { Reg = Reg->getMostDerivedObjectRegion(); return State->get<IteratorRegionMap>(Reg); } else if (const auto Sym = Val.getAsSymbol()) { return State->get<IteratorSymbolMap>(Sym); } else if (const auto LCVal = Val.getAs<nonloc::LazyCompoundVal>()) { return State->get<IteratorRegionMap>(LCVal->getRegion()); } return nullptr; } ProgramStateRef setIteratorPosition(ProgramStateRef State, const SVal &Val, const IteratorPosition &Pos) { if (auto Reg = Val.getAsRegion()) { Reg = Reg->getMostDerivedObjectRegion(); return State->set<IteratorRegionMap>(Reg, Pos); } else if (const auto Sym = Val.getAsSymbol()) { return State->set<IteratorSymbolMap>(Sym, Pos); } else if (const auto LCVal = Val.getAs<nonloc::LazyCompoundVal>()) { return State->set<IteratorRegionMap>(LCVal->getRegion(), Pos); } return nullptr; } ProgramStateRef createIteratorPosition(ProgramStateRef State, const SVal &Val, const MemRegion *Cont, const Stmt* S, const LocationContext *LCtx, unsigned blockCount) { auto &StateMgr = State->getStateManager(); auto &SymMgr = StateMgr.getSymbolManager(); auto &ACtx = StateMgr.getContext(); auto Sym = SymMgr.conjureSymbol(S, LCtx, ACtx.LongTy, blockCount); State = assumeNoOverflow(State, Sym, 4); return setIteratorPosition(State, Val, IteratorPosition::getPosition(Cont, Sym)); } ProgramStateRef advancePosition(ProgramStateRef State, const SVal &Iter, OverloadedOperatorKind Op, const SVal &Distance) { const auto *Pos = getIteratorPosition(State, Iter); if (!Pos) return nullptr; auto &SymMgr = State->getStateManager().getSymbolManager(); auto &SVB = State->getStateManager().getSValBuilder(); auto &BVF = State->getStateManager().getBasicVals(); assert ((Op == OO_Plus || Op == OO_PlusEqual || Op == OO_Minus || Op == OO_MinusEqual) && "Advance operator must be one of +, -, += and -=."); auto BinOp = (Op == OO_Plus || Op == OO_PlusEqual) ? BO_Add : BO_Sub; const auto IntDistOp = Distance.getAs<nonloc::ConcreteInt>(); if (!IntDistOp) return nullptr; // For concrete integers we can calculate the new position nonloc::ConcreteInt IntDist = *IntDistOp; if (IntDist.getValue().isNegative()) { IntDist = nonloc::ConcreteInt(BVF.getValue(-IntDist.getValue())); BinOp = (BinOp == BO_Add) ? BO_Sub : BO_Add; } const auto NewPos = Pos->setTo(SVB.evalBinOp(State, BinOp, nonloc::SymbolVal(Pos->getOffset()), IntDist, SymMgr.getType(Pos->getOffset())) .getAsSymbol()); return setIteratorPosition(State, Iter, NewPos); } // This function tells the analyzer's engine that symbols produced by our // checker, most notably iterator positions, are relatively small. // A distance between items in the container should not be very large. // By assuming that it is within around 1/8 of the address space, // we can help the analyzer perform operations on these symbols // without being afraid of integer overflows. // FIXME: Should we provide it as an API, so that all checkers could use it? ProgramStateRef assumeNoOverflow(ProgramStateRef State, SymbolRef Sym, long Scale) { SValBuilder &SVB = State->getStateManager().getSValBuilder(); BasicValueFactory &BV = SVB.getBasicValueFactory(); QualType T = Sym->getType(); assert(T->isSignedIntegerOrEnumerationType()); APSIntType AT = BV.getAPSIntType(T); ProgramStateRef NewState = State; llvm::APSInt Max = AT.getMaxValue() / AT.getValue(Scale); SVal IsCappedFromAbove = SVB.evalBinOpNN(State, BO_LE, nonloc::SymbolVal(Sym), nonloc::ConcreteInt(Max), SVB.getConditionType()); if (auto DV = IsCappedFromAbove.getAs<DefinedSVal>()) { NewState = NewState->assume(*DV, true); if (!NewState) return State; } llvm::APSInt Min = -Max; SVal IsCappedFromBelow = SVB.evalBinOpNN(State, BO_GE, nonloc::SymbolVal(Sym), nonloc::ConcreteInt(Min), SVB.getConditionType()); if (auto DV = IsCappedFromBelow.getAs<DefinedSVal>()) { NewState = NewState->assume(*DV, true); if (!NewState) return State; } return NewState; } bool compare(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2, BinaryOperator::Opcode Opc) { return compare(State, nonloc::SymbolVal(Sym1), nonloc::SymbolVal(Sym2), Opc); } bool compare(ProgramStateRef State, NonLoc NL1, NonLoc NL2, BinaryOperator::Opcode Opc) { auto &SVB = State->getStateManager().getSValBuilder(); const auto comparison = SVB.evalBinOp(State, Opc, NL1, NL2, SVB.getConditionType()); assert(comparison.getAs<DefinedSVal>() && "Symbol comparison must be a `DefinedSVal`"); return !State->assume(comparison.castAs<DefinedSVal>(), false); } } // namespace iterator } // namespace ento } // namespace clang
Upload File
Create Folder