26 #include "llvm/ADT/SmallString.h"
27 #include "llvm/Support/raw_ostream.h"
29 using namespace clang;
40 class NSErrorMethodChecker
41 :
public Checker< check::ASTDecl<ObjCMethodDecl> > {
45 NSErrorMethodChecker() : II(nullptr) {}
61 II = &D->getASTContext().Idents.get(
"NSError");
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 "
78 "Coding conventions (Apple)", err, L);
87 class CFErrorFunctionChecker
88 :
public Checker< check::ASTDecl<FunctionDecl> > {
92 CFErrorFunctionChecker() : II(nullptr) {}
99 void CFErrorFunctionChecker::checkASTDecl(
const FunctionDecl *D,
108 II = &D->getASTContext().Idents.get(
"CFErrorRef");
110 bool hasCFError =
false;
119 const char *err =
"Function accepting CFErrorRef* "
120 "should have a non-void return value to indicate whether or not an "
124 BR.
EmitBasicReport(D,
this,
"Bad return type when passing CFErrorRef*",
125 "Coding conventions (Apple)", err, L);
135 class NSErrorDerefBug :
public BugType {
138 :
BugType(Checker,
"NSError** null dereference",
139 "Coding conventions (Apple)") {}
142 class CFErrorDerefBug :
public BugType {
145 :
BugType(Checker,
"CFErrorRef* null dereference",
146 "Coding conventions (Apple)") {}
152 class NSOrCFErrorDerefChecker
153 :
public Checker< check::Location,
154 check::Event<ImplicitNullDerefEvent> > {
156 mutable std::unique_ptr<NSErrorDerefBug> NSBT;
157 mutable std::unique_ptr<CFErrorDerefBug> CFBT;
159 bool ShouldCheckNSError, ShouldCheckCFError;
160 NSOrCFErrorDerefChecker() : NSErrorII(nullptr), CFErrorII(nullptr),
161 ShouldCheckNSError(0), ShouldCheckCFError(0) { }
163 void checkLocation(
SVal loc,
bool isLoad,
const Stmt *
S,
173 template <typename T>
176 if (
const unsigned *attachedFlags = state->get<T>(sym))
177 return *attachedFlags;
181 template <
typename T>
195 stackReg = dyn_cast<StackArgumentsSpaceRegion>(VR->getMemorySpace()))
196 if (stackReg->getStackFrame() == SFC)
197 return VR->getValueType();
203 void NSOrCFErrorDerefChecker::checkLocation(
SVal loc,
bool isLoad,
227 CFErrorII = &Ctx.
Idents.
get(
"CFErrorRef");
229 if (ShouldCheckNSError &&
IsNSError(parmT, NSErrorII)) {
234 if (ShouldCheckCFError &&
IsCFError(parmT, CFErrorII)) {
244 SVal loc =
event.Location;
248 bool isNSError = hasFlag<NSErrorOut>(loc,
state);
249 bool isCFError =
false;
251 isCFError = hasFlag<CFErrorOut>(loc,
state);
253 if (!(isNSError || isCFError))
258 llvm::raw_svector_ostream os(Buf);
260 os <<
"Potential null dereference. According to coding standards ";
262 ?
"in 'Creating and Returning NSError Objects' the parameter"
263 :
"documented in CoreFoundation/CFError.h the parameter");
265 os <<
" may be null";
270 NSBT.reset(
new NSErrorDerefBug(
this));
275 CFBT.reset(
new CFErrorDerefBug(
this));
278 BR.
emitReport(llvm::make_unique<BugReport>(*bug, os.str(),
event.SinkNode));
304 if (!PPT)
return false;
307 if (!TT)
return false;
314 NSOrCFErrorDerefChecker *checker =
316 checker->ShouldCheckNSError =
true;
321 NSOrCFErrorDerefChecker *checker =
323 checker->ShouldCheckCFError =
true;
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
const RegionTy * getAs() const
static bool IsCFError(QualType T, IdentifierInfo *II)
ObjCMethodDecl - Represents an instance or class method declaration.
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getReturnType() const
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
llvm::ImmutableMap< SymbolRef, unsigned > ErrorOutFlag
Represents an ObjC class declaration.
detail::InMemoryDirectory::const_iterator I
We dereferenced a location that may be null.
const ProgramStateRef & getState() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
static void setFlag(ProgramStateRef state, SVal val, CheckerContext &C)
BugReporter is a utility class for generating PathDiagnostics for analysis.
ArrayRef< ParmVarDecl * > parameters() const
bool doesThisDeclarationHaveABody() const
doesThisDeclarationHaveABody - Returns whether this specific declaration of the function has a body -...
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type)
Declares a program state trait for type Type called Name, and introduce a typedef named NameTy...
CHECKER * registerChecker()
Used to register checkers.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges=None)
const StackFrameContext * getCurrentStackFrame() const
void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
ArrayRef< ParmVarDecl * > parameters() const
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
TypedefNameDecl * getDecl() const
QualType getReturnType() const
static bool hasFlag(SVal val, ProgramStateRef state)
QualType getPointeeType() const
ASTContext & getASTContext()
Represents a pointer to an Objective C object.
const T * getAs() const
Member-template getAs<specific type>'.
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
SourceManager & getSourceManager()
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
static bool IsNSError(QualType T, IdentifierInfo *II)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
static QualType parameterTypeFromSVal(SVal val, CheckerContext &C)
const LocationContext * getLocationContext() const