31 #include "llvm/ADT/DenseMap.h" 33 using namespace clang;
52 class DirectIvarAssignment :
53 public Checker<check::ASTDecl<ObjCImplementationDecl> > {
61 const IvarToPropertyMapTy &IvarToPropMap;
65 const CheckerBase *Checker;
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) {
89 DirectIvarAssignment() : ShouldSkipMethod(&DefaultMethodFilter) {}
92 BugReporter &BR)
const;
95 static const ObjCIvarDecl *findPropertyBackingIvar(
const ObjCPropertyDecl *PD,
118 AnalysisManager& Mgr,
119 BugReporter &BR)
const {
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) {
158 if (Ann->getAnnotation() ==
159 "objc_allow_direct_instance_variable_assignment")
164 void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator(
175 if (
const ObjCIvarDecl *D = IvarRef->
getDecl()) {
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",
203 PathDiagnosticLocation(IvarRef, BR.getSourceManager(), DCtx));
211 void ento::registerDirectIvarAssignment(CheckerManager &mgr) {
212 mgr.registerChecker<DirectIvarAssignment>();
219 if (Ann->getAnnotation() ==
"objc_no_direct_instance_variable_assignment")
224 void ento::registerDirectIvarAssignmentForAnnotatedFunctions(
225 CheckerManager &mgr) {
226 mgr.registerChecker<DirectIvarAssignment>()->ShouldSkipMethod = &
AttrFilter;
const char *const CoreFoundationObjectiveC
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
Decl - This represents one declaration (or definition), e.g.
static bool AttrFilter(const ObjCMethodDecl *M)
ObjCMethodDecl - Represents an instance or class method declaration.
static bool isAssignmentOp(Opcode Opc)
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
instprop_range instance_properties() const
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.
instmeth_range instance_methods() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
A builtin binary operation expression such as "x + y" or "x <= y".
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
Represents an ObjC class declaration.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Selector getSetterName() const
IdentifierInfo * getDefaultSynthIvarName(ASTContext &Ctx) const
Get the default name of the synthesized ivar.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
llvm::PointerUnion< const LocationContext *, AnalysisDeclContext * > LocationOrAnalysisDeclContext
Selector getSelector() const
ASTContext & getASTContext() const LLVM_READONLY
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Represents one property declaration in an Objective-C interface.
const ObjCInterfaceDecl * getClassInterface() const
Dataflow Directional Tag Classes.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
ObjCIvarRefExpr - A reference to an ObjC instance variable.
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCIvarDecl * getPropertyIvarDecl() const
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
Selector getGetterName() const