30 #include "llvm/ADT/DenseMap.h" 32 using namespace clang;
51 class DirectIvarAssignment :
52 public Checker<check::ASTDecl<ObjCImplementationDecl> > {
60 const IvarToPropertyMapTy &IvarToPropMap;
64 const CheckerBase *Checker;
68 MethodCrawler(
const IvarToPropertyMapTy &InMap,
const ObjCMethodDecl *InMD,
71 : IvarToPropMap(InMap), MD(InMD), InterfD(InID), BR(InBR),
72 Checker(Checker), DCtx(InDCtx) {}
74 void VisitStmt(
const Stmt *S) { VisitChildren(S); }
78 void VisitChildren(
const Stmt *S) {
88 DirectIvarAssignment() : ShouldSkipMethod(&DefaultMethodFilter) {}
91 BugReporter &BR)
const;
94 static const ObjCIvarDecl *findPropertyBackingIvar(
const ObjCPropertyDecl *PD,
117 AnalysisManager& Mgr,
118 BugReporter &BR)
const {
122 IvarToPropertyMapTy IvarToPropMap;
127 const ObjCIvarDecl *ID = findPropertyBackingIvar(PD, InterD,
134 IvarToPropMap[
ID] = PD;
137 if (IvarToPropMap.empty())
143 if ((*ShouldSkipMethod)(M))
155 static bool isAnnotatedToAllowDirectAssignment(
const Decl *D) {
157 if (Ann->getAnnotation() ==
158 "objc_allow_direct_instance_variable_assignment")
163 void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator(
174 if (
const ObjCIvarDecl *D = IvarRef->
getDecl()) {
175 IvarToPropertyMapTy::const_iterator I = IvarToPropMap.find(D);
177 if (I != IvarToPropMap.end()) {
183 if (isAnnotatedToAllowDirectAssignment(PD) ||
184 isAnnotatedToAllowDirectAssignment(D))
200 "Direct assignment to an instance variable backing a property; " 201 "use the setter instead",
202 PathDiagnosticLocation(IvarRef, BR.getSourceManager(), DCtx));
212 if (Ann->getAnnotation() ==
"objc_no_direct_instance_variable_assignment")
219 void ento::registerDirectIvarAssignment(CheckerManager &mgr) {
220 mgr.registerChecker<DirectIvarAssignment>();
223 bool ento::shouldRegisterDirectIvarAssignment(
const LangOptions &LO) {
227 void ento::registerDirectIvarAssignmentForAnnotatedFunctions(
228 CheckerManager &mgr) {
229 mgr.getChecker<DirectIvarAssignment>()->ShouldSkipMethod = &
AttrFilter;
232 bool ento::shouldRegisterDirectIvarAssignmentForAnnotatedFunctions(
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
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
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