25#include "llvm/ADT/SmallString.h" 
   26#include "llvm/Support/raw_ostream.h" 
   40class NSErrorMethodChecker
 
   41    : 
public Checker< check::ASTDecl<ObjCMethodDecl> > {
 
   42  mutable IdentifierInfo *II = 
nullptr;
 
   45  NSErrorMethodChecker() = 
default;
 
   47  void checkASTDecl(
const ObjCMethodDecl *D,
 
   48                    AnalysisManager &mgr, BugReporter &BR) 
const;
 
   63  bool hasNSError = 
false;
 
   72    const char *err = 
"Method accepting NSError** " 
   73        "should have a non-void return value to indicate whether or not an " 
   75    PathDiagnosticLocation L =
 
   78                       "Coding conventions (Apple)", err, L);
 
   87class CFErrorFunctionChecker
 
   88    : 
public Checker< check::ASTDecl<FunctionDecl> > {
 
   89  mutable IdentifierInfo *II;
 
   92  CFErrorFunctionChecker() : II(
nullptr) {}
 
   94  void checkASTDecl(
const FunctionDecl *D,
 
   95                    AnalysisManager &mgr, BugReporter &BR) 
const;
 
  108void CFErrorFunctionChecker::checkASTDecl(
const FunctionDecl *D,
 
  109                                        AnalysisManager &mgr,
 
  110                                        BugReporter &BR)
 const {
 
  121  bool hasCFError = 
false;
 
  130    const char *err = 
"Function accepting CFErrorRef* " 
  131        "should have a non-void return value to indicate whether or not an " 
  133    PathDiagnosticLocation L =
 
  135    BR.
EmitBasicReport(D, 
this, 
"Bad return type when passing CFErrorRef*",
 
  136                       "Coding conventions (Apple)", err, L);
 
  145class NSOrCFErrorDerefChecker
 
  146    : 
public CheckerFamily<check::Location,
 
  147                           check::Event<ImplicitNullDerefEvent>> {
 
  148  mutable IdentifierInfo *NSErrorII = 
nullptr;
 
  149  mutable IdentifierInfo *CFErrorII = 
nullptr;
 
  152  CheckerFrontendWithBugType NSError{
"NSError** null dereference",
 
  153                                     "Coding conventions (Apple)"};
 
  154  CheckerFrontendWithBugType CFError{
"CFErrorRef* null dereference",
 
  155                                     "Coding conventions (Apple)"};
 
  157  StringRef getDebugTag()
 const override { 
return "NSOrCFErrorDerefChecker"; }
 
  159  void checkLocation(SVal loc, 
bool isLoad, 
const Stmt *S,
 
  160                     CheckerContext &
C) 
const;
 
  161  void checkEvent(ImplicitNullDerefEvent event) 
const;
 
  172    if (
const unsigned *attachedFlags = state->get<
T>(sym))
 
  173      return *attachedFlags;
 
 
  181    C.addTransition(state->set<
T>(sym, 
true));
 
 
  189      if (
const auto *StackSpace =
 
  191        if (StackSpace->getStackFrame() == SFC)
 
  192          return VR->getValueType();
 
 
  198void NSOrCFErrorDerefChecker::checkLocation(SVal loc, 
bool isLoad,
 
  200                                            CheckerContext &
C)
 const {
 
  206  ASTContext &Ctx = 
C.getASTContext();
 
  222    CFErrorII = &Ctx.
Idents.
get(
"CFErrorRef");
 
  235void NSOrCFErrorDerefChecker::checkEvent(ImplicitNullDerefEvent event)
 const {
 
  239  SVal loc = 
event.Location;
 
  241  BugReporter &BR = *
event.BR;
 
  244  bool isCFError = 
false;
 
  248  if (!(isNSError || isCFError))
 
  252  SmallString<128> Buf;
 
  253  llvm::raw_svector_ostream os(Buf);
 
  255  os << 
"Potential null dereference. According to coding standards ";
 
  257         ? 
"in 'Creating and Returning NSError Objects' the parameter" 
  258         : 
"documented in CoreFoundation/CFError.h the parameter");
 
  260  os  << 
" may be null";
 
  262  const BugType &BT = isNSError ? NSError : CFError;
 
  264      std::make_unique<PathSensitiveBugReport>(BT, os.str(), event.
SinkNode));
 
  283    return II == ID->getIdentifier();
 
 
  290  if (!PPT) 
return false;
 
  293  if (!TT) 
return false;
 
 
  304#define REGISTER_CHECKER(NAME, ADDITIONAL_PART)                                \ 
  305  void ento::register##NAME##Checker(CheckerManager &Mgr) {                    \ 
  306    Mgr.getChecker<NSOrCFErrorDerefChecker>()->NAME.enable(Mgr);               \ 
  307    Mgr.registerChecker<ADDITIONAL_PART>();                                    \ 
  310  bool ento::shouldRegister##NAME##Checker(const CheckerManager &) {           \ 
 
#define REGISTER_CHECKER(name)
 
static bool hasFlag(SVal val, ProgramStateRef state)
 
static bool IsCFError(QualType T, IdentifierInfo *II)
 
static void setFlag(ProgramStateRef state, SVal val, CheckerContext &C)
 
static QualType parameterTypeFromSVal(SVal val, CheckerContext &C)
 
static bool IsNSError(QualType T, IdentifierInfo *II)
 
static bool hasReservedReturnType(const FunctionDecl *D)
 
llvm::ImmutableMap< SymbolRef, unsigned > ErrorOutFlag
 
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type)
Declares a program state trait for type Type called Name, and introduce a type named NameTy.
 
ASTContext & getASTContext() const LLVM_READONLY
 
Represents a function declaration or definition.
 
QualType getReturnType() const
 
ArrayRef< ParmVarDecl * > parameters() const
 
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
 
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
 
One of these records is kept for each identifier that is lexed.
 
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
 
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
 
Represents an ObjC class declaration.
 
ObjCMethodDecl - Represents an instance or class method declaration.
 
ArrayRef< ParmVarDecl * > parameters() const
 
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
 
QualType getReturnType() const
 
Represents a pointer to an Objective C object.
 
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface.
 
PointerType - C99 6.7.5.1 - Pointer Declarators.
 
QualType getPointeeType() const
 
A (possibly-)qualified type.
 
bool isNull() const
Return true if this QualType doesn't point to a type yet.
 
It represents a stack frame of the call stack (based on CallEvent).
 
const T * getAs() const
Member-template getAs<specific type>'.
 
TypedefNameDecl * getDecl() const
 
BugReporter is a utility class for generating PathDiagnostics for analysis.
 
const SourceManager & getSourceManager()
 
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerFrontend *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges={}, ArrayRef< FixItHint > Fixits={})
 
virtual void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
 
Simple checker classes that implement one frontend (i.e.
 
MemRegion - The root abstract class for all memory regions.
 
const RegionTy * getAs() const
 
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
 
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.
 
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
 
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
 
const SymExpr * SymbolRef
 
The JSON file list parser is used to communicate input to InstallAPI.
 
bool isa(CodeGen::Address addr)
 
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
 
const FunctionProtoType * T