31 #include "llvm/ADT/DenseMap.h"
33 using namespace clang;
53 class DirectIvarAssignment :
54 public Checker<check::ASTDecl<ObjCImplementationDecl> > {
62 const IvarToPropertyMapTy &IvarToPropMap;
70 MethodCrawler(
const IvarToPropertyMapTy &InMap,
const ObjCMethodDecl *InMD,
73 : IvarToPropMap(InMap), MD(InMD), InterfD(InID), BR(InBR),
74 Checker(Checker), DCtx(InDCtx) {}
76 void VisitStmt(
const Stmt *
S) { VisitChildren(S); }
80 void VisitChildren(
const Stmt *
S) {
81 for (
const Stmt *Child : S->children())
90 DirectIvarAssignment() : ShouldSkipMethod(&DefaultMethodFilter) {}
124 IvarToPropertyMapTy IvarToPropMap;
129 const ObjCIvarDecl *ID = findPropertyBackingIvar(PD, InterD,
136 IvarToPropMap[
ID] = PD;
139 if (IvarToPropMap.empty())
145 if ((*ShouldSkipMethod)(M))
157 static bool isAnnotatedToAllowDirectAssignment(
const Decl *D) {
159 if (Ann->getAnnotation() ==
160 "objc_allow_direct_instance_variable_assignment")
165 void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator(
177 IvarToPropertyMapTy::const_iterator I = IvarToPropMap.find(D);
179 if (I != IvarToPropMap.end()) {
185 if (isAnnotatedToAllowDirectAssignment(PD) ||
186 isAnnotatedToAllowDirectAssignment(D))
202 "Direct assignment to an instance variable backing a property; "
203 "use the setter instead",
220 if (Ann->getAnnotation() ==
"objc_no_direct_instance_variable_assignment")
225 void ento::registerDirectIvarAssignmentForAnnotatedFunctions(
const char *const CoreFoundationObjectiveC
IdentifierInfo * getIdentifier() const
static bool AttrFilter(const ObjCMethodDecl *M)
static bool isAssignmentOp(Opcode Opc)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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
Represents an ObjC class declaration.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
ASTContext & getASTContext() override
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
ID
Defines the set of possible language-specific address spaces.
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
llvm::PointerUnion< const LocationContext *, AnalysisDeclContext * > LocationOrAnalysisDeclContext
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
prop_range properties() const
ObjCIvarDecl * getPropertyIvarDecl() const
Selector getGetterName() const
Selector getSelector() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
IdentifierInfo * getDefaultSynthIvarName(ASTContext &Ctx) const
Get the default name of the synthesized ivar.