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: NSErrorChecker.cpp
//=- NSErrorChecker.cpp - Coding conventions for uses of NSError -*- 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 // //===----------------------------------------------------------------------===// // // This file defines a CheckNSError, a flow-insenstive check // that determines if an Objective-C class interface correctly returns // a non-void return type. // // File under feature request PR 2600. // //===----------------------------------------------------------------------===// #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/raw_ostream.h" using namespace clang; using namespace ento; static bool IsNSError(QualType T, IdentifierInfo *II); static bool IsCFError(QualType T, IdentifierInfo *II); //===----------------------------------------------------------------------===// // NSErrorMethodChecker //===----------------------------------------------------------------------===// namespace { class NSErrorMethodChecker : public Checker< check::ASTDecl<ObjCMethodDecl> > { mutable IdentifierInfo *II; public: NSErrorMethodChecker() : II(nullptr) {} void checkASTDecl(const ObjCMethodDecl *D, AnalysisManager &mgr, BugReporter &BR) const; }; } void NSErrorMethodChecker::checkASTDecl(const ObjCMethodDecl *D, AnalysisManager &mgr, BugReporter &BR) const { if (!D->isThisDeclarationADefinition()) return; if (!D->getReturnType()->isVoidType()) return; if (!II) II = &D->getASTContext().Idents.get("NSError"); bool hasNSError = false; for (const auto *I : D->parameters()) { if (IsNSError(I->getType(), II)) { hasNSError = true; break; } } if (hasNSError) { const char *err = "Method accepting NSError** " "should have a non-void return value to indicate whether or not an " "error occurred"; PathDiagnosticLocation L = PathDiagnosticLocation::create(D, BR.getSourceManager()); BR.EmitBasicReport(D, this, "Bad return type when passing NSError**", "Coding conventions (Apple)", err, L); } } //===----------------------------------------------------------------------===// // CFErrorFunctionChecker //===----------------------------------------------------------------------===// namespace { class CFErrorFunctionChecker : public Checker< check::ASTDecl<FunctionDecl> > { mutable IdentifierInfo *II; public: CFErrorFunctionChecker() : II(nullptr) {} void checkASTDecl(const FunctionDecl *D, AnalysisManager &mgr, BugReporter &BR) const; }; } static bool hasReservedReturnType(const FunctionDecl *D) { if (isa<CXXConstructorDecl>(D)) return true; // operators delete and delete[] are required to have 'void' return type auto OperatorKind = D->getOverloadedOperator(); return OperatorKind == OO_Delete || OperatorKind == OO_Array_Delete; } void CFErrorFunctionChecker::checkASTDecl(const FunctionDecl *D, AnalysisManager &mgr, BugReporter &BR) const { if (!D->doesThisDeclarationHaveABody()) return; if (!D->getReturnType()->isVoidType()) return; if (hasReservedReturnType(D)) return; if (!II) II = &D->getASTContext().Idents.get("CFErrorRef"); bool hasCFError = false; for (auto I : D->parameters()) { if (IsCFError(I->getType(), II)) { hasCFError = true; break; } } if (hasCFError) { const char *err = "Function accepting CFErrorRef* " "should have a non-void return value to indicate whether or not an " "error occurred"; PathDiagnosticLocation L = PathDiagnosticLocation::create(D, BR.getSourceManager()); BR.EmitBasicReport(D, this, "Bad return type when passing CFErrorRef*", "Coding conventions (Apple)", err, L); } } //===----------------------------------------------------------------------===// // NSOrCFErrorDerefChecker //===----------------------------------------------------------------------===// namespace { class NSErrorDerefBug : public BugType { public: NSErrorDerefBug(const CheckerNameRef Checker) : BugType(Checker, "NSError** null dereference", "Coding conventions (Apple)") {} }; class CFErrorDerefBug : public BugType { public: CFErrorDerefBug(const CheckerNameRef Checker) : BugType(Checker, "CFErrorRef* null dereference", "Coding conventions (Apple)") {} }; } namespace { class NSOrCFErrorDerefChecker : public Checker< check::Location, check::Event<ImplicitNullDerefEvent> > { mutable IdentifierInfo *NSErrorII, *CFErrorII; mutable std::unique_ptr<NSErrorDerefBug> NSBT; mutable std::unique_ptr<CFErrorDerefBug> CFBT; public: DefaultBool ShouldCheckNSError, ShouldCheckCFError; CheckerNameRef NSErrorName, CFErrorName; NSOrCFErrorDerefChecker() : NSErrorII(nullptr), CFErrorII(nullptr) {} void checkLocation(SVal loc, bool isLoad, const Stmt *S, CheckerContext &C) const; void checkEvent(ImplicitNullDerefEvent event) const; }; } typedef llvm::ImmutableMap<SymbolRef, unsigned> ErrorOutFlag; REGISTER_TRAIT_WITH_PROGRAMSTATE(NSErrorOut, ErrorOutFlag) REGISTER_TRAIT_WITH_PROGRAMSTATE(CFErrorOut, ErrorOutFlag) template <typename T> static bool hasFlag(SVal val, ProgramStateRef state) { if (SymbolRef sym = val.getAsSymbol()) if (const unsigned *attachedFlags = state->get<T>(sym)) return *attachedFlags; return false; } template <typename T> static void setFlag(ProgramStateRef state, SVal val, CheckerContext &C) { // We tag the symbol that the SVal wraps. if (SymbolRef sym = val.getAsSymbol()) C.addTransition(state->set<T>(sym, true)); } static QualType parameterTypeFromSVal(SVal val, CheckerContext &C) { const StackFrameContext * SFC = C.getStackFrame(); if (Optional<loc::MemRegionVal> X = val.getAs<loc::MemRegionVal>()) { const MemRegion* R = X->getRegion(); if (const VarRegion *VR = R->getAs<VarRegion>()) if (const StackArgumentsSpaceRegion * stackReg = dyn_cast<StackArgumentsSpaceRegion>(VR->getMemorySpace())) if (stackReg->getStackFrame() == SFC) return VR->getValueType(); } return QualType(); } void NSOrCFErrorDerefChecker::checkLocation(SVal loc, bool isLoad, const Stmt *S, CheckerContext &C) const { if (!isLoad) return; if (loc.isUndef() || !loc.getAs<Loc>()) return; ASTContext &Ctx = C.getASTContext(); ProgramStateRef state = C.getState(); // If we are loading from NSError**/CFErrorRef* parameter, mark the resulting // SVal so that we can later check it when handling the // ImplicitNullDerefEvent event. // FIXME: Cumbersome! Maybe add hook at construction of SVals at start of // function ? QualType parmT = parameterTypeFromSVal(loc, C); if (parmT.isNull()) return; if (!NSErrorII) NSErrorII = &Ctx.Idents.get("NSError"); if (!CFErrorII) CFErrorII = &Ctx.Idents.get("CFErrorRef"); if (ShouldCheckNSError && IsNSError(parmT, NSErrorII)) { setFlag<NSErrorOut>(state, state->getSVal(loc.castAs<Loc>()), C); return; } if (ShouldCheckCFError && IsCFError(parmT, CFErrorII)) { setFlag<CFErrorOut>(state, state->getSVal(loc.castAs<Loc>()), C); return; } } void NSOrCFErrorDerefChecker::checkEvent(ImplicitNullDerefEvent event) const { if (event.IsLoad) return; SVal loc = event.Location; ProgramStateRef state = event.SinkNode->getState(); BugReporter &BR = *event.BR; bool isNSError = hasFlag<NSErrorOut>(loc, state); bool isCFError = false; if (!isNSError) isCFError = hasFlag<CFErrorOut>(loc, state); if (!(isNSError || isCFError)) return; // Storing to possible null NSError/CFErrorRef out parameter. SmallString<128> Buf; llvm::raw_svector_ostream os(Buf); os << "Potential null dereference. According to coding standards "; os << (isNSError ? "in 'Creating and Returning NSError Objects' the parameter" : "documented in CoreFoundation/CFError.h the parameter"); os << " may be null"; BugType *bug = nullptr; if (isNSError) { if (!NSBT) NSBT.reset(new NSErrorDerefBug(NSErrorName)); bug = NSBT.get(); } else { if (!CFBT) CFBT.reset(new CFErrorDerefBug(CFErrorName)); bug = CFBT.get(); } BR.emitReport( std::make_unique<PathSensitiveBugReport>(*bug, os.str(), event.SinkNode)); } static bool IsNSError(QualType T, IdentifierInfo *II) { const PointerType* PPT = T->getAs<PointerType>(); if (!PPT) return false; const ObjCObjectPointerType* PT = PPT->getPointeeType()->getAs<ObjCObjectPointerType>(); if (!PT) return false; const ObjCInterfaceDecl *ID = PT->getInterfaceDecl(); // FIXME: Can ID ever be NULL? if (ID) return II == ID->getIdentifier(); return false; } static bool IsCFError(QualType T, IdentifierInfo *II) { const PointerType* PPT = T->getAs<PointerType>(); if (!PPT) return false; const TypedefType* TT = PPT->getPointeeType()->getAs<TypedefType>(); if (!TT) return false; return TT->getDecl()->getIdentifier() == II; } void ento::registerNSOrCFErrorDerefChecker(CheckerManager &mgr) { mgr.registerChecker<NSOrCFErrorDerefChecker>(); } bool ento::shouldRegisterNSOrCFErrorDerefChecker(const CheckerManager &mgr) { return true; } void ento::registerNSErrorChecker(CheckerManager &mgr) { mgr.registerChecker<NSErrorMethodChecker>(); NSOrCFErrorDerefChecker *checker = mgr.getChecker<NSOrCFErrorDerefChecker>(); checker->ShouldCheckNSError = true; checker->NSErrorName = mgr.getCurrentCheckerName(); } bool ento::shouldRegisterNSErrorChecker(const CheckerManager &mgr) { return true; } void ento::registerCFErrorChecker(CheckerManager &mgr) { mgr.registerChecker<CFErrorFunctionChecker>(); NSOrCFErrorDerefChecker *checker = mgr.getChecker<NSOrCFErrorDerefChecker>(); checker->ShouldCheckCFError = true; checker->CFErrorName = mgr.getCurrentCheckerName(); } bool ento::shouldRegisterCFErrorChecker(const CheckerManager &mgr) { return true; }
Upload File
Create Folder