31 #include "llvm/ADT/DenseMap.h"
33 using namespace clang;
52 class DirectIvarAssignment :
53 public Checker<check::ASTDecl<ObjCImplementationDecl> > {
61 const IvarToPropertyMapTy &IvarToPropMap;
69 MethodCrawler(
const IvarToPropertyMapTy &InMap,
const ObjCMethodDecl *InMD,
72 : IvarToPropMap(InMap), MD(InMD), InterfD(InID), BR(InBR),
73 Checker(Checker), DCtx(InDCtx) {}
75 void VisitStmt(
const Stmt *
S) { VisitChildren(S); }
79 void VisitChildren(
const Stmt *
S) {
80 for (
const Stmt *Child : S->children())
89 DirectIvarAssignment() : ShouldSkipMethod(&DefaultMethodFilter) {}
123 IvarToPropertyMapTy IvarToPropMap;
128 const ObjCIvarDecl *ID = findPropertyBackingIvar(PD, InterD,
135 IvarToPropMap[
ID] = PD;
138 if (IvarToPropMap.empty())
144 if ((*ShouldSkipMethod)(M))
156 static bool isAnnotatedToAllowDirectAssignment(
const Decl *D) {
157 for (
const auto *Ann : D->specific_attrs<AnnotateAttr>())
158 if (Ann->getAnnotation() ==
159 "objc_allow_direct_instance_variable_assignment")
164 void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator(
176 IvarToPropertyMapTy::const_iterator
I = IvarToPropMap.find(D);
178 if (I != IvarToPropMap.end()) {
184 if (isAnnotatedToAllowDirectAssignment(PD) ||
185 isAnnotatedToAllowDirectAssignment(D))
201 "Direct assignment to an instance variable backing a property; "
202 "use the setter instead",
218 for (
const auto *Ann : M->specific_attrs<AnnotateAttr>())
219 if (Ann->getAnnotation() ==
"objc_no_direct_instance_variable_assignment")
224 void ento::registerDirectIvarAssignmentForAnnotatedFunctions(
const char *const CoreFoundationObjectiveC
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
static bool AttrFilter(const ObjCMethodDecl *M)
ObjCMethodDecl - Represents an instance or class method declaration.
static bool isAssignmentOp(Opcode Opc)
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 ...
AnalysisDeclContext contains the context data for the function or method under analysis.
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
A builtin binary operation expression such as "x + y" or "x <= y".
Selector getSetterName() const
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
Represents an ObjC class declaration.
detail::InMemoryDirectory::const_iterator I
ObjCMethodDecl * getCanonicalDecl() override
ASTContext & getASTContext() override
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
llvm::PointerUnion< const LocationContext *, AnalysisDeclContext * > LocationOrAnalysisDeclContext
BugReporter is a utility class for generating PathDiagnostics for analysis.
CHECKER * registerChecker()
Used to register checkers.
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges=None)
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
const ObjCInterfaceDecl * getClassInterface() const
Represents one property declaration in an Objective-C interface.
instmeth_range instance_methods() const
ObjCIvarDecl * getPropertyIvarDecl() const
Selector getGetterName() const
Selector getSelector() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
instprop_range instance_properties() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
ObjCIvarDecl - Represents an ObjC instance variable.
IdentifierInfo * getDefaultSynthIvarName(ASTContext &Ctx) const
Get the default name of the synthesized ivar.