//===- DirectIvarAssignment.cpp - Check rules on ObjC properties -*- C++ -*-==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Check that Objective C properties are set with the setter, not though a // direct assignment. // // Two versions of a checker exist: one that checks all methods and the other // that only checks the methods annotated with // __attribute__((annotate("objc_no_direct_instance_variable_assignment"))) // // The checker does not warn about assignments to Ivars, annotated with // __attribute__((objc_allow_direct_instance_variable_assignment"))). This // annotation serves as a false positive suppression mechanism for the // checker. The annotation is allowed on properties and Ivars. // //===----------------------------------------------------------------------===// #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/StmtVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "llvm/ADT/DenseMap.h" usingnamespaceclang; usingnamespaceento; namespace { /// The default method filter, which is used to filter out the methods on which /// the check should not be performed. /// /// Checks for the init, dealloc, and any other functions that might be allowed /// to perform direct instance variable assignment based on their name. static bool DefaultMethodFilter(const ObjCMethodDecl *M) { … } class DirectIvarAssignment : public Checker<check::ASTDecl<ObjCImplementationDecl> > { … }; static const ObjCIvarDecl *findPropertyBackingIvar(const ObjCPropertyDecl *PD, const ObjCInterfaceDecl *InterD, ASTContext &Ctx) { … } void DirectIvarAssignment::checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager& Mgr, BugReporter &BR) const { … } static bool isAnnotatedToAllowDirectAssignment(const Decl *D) { … } void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator( const BinaryOperator *BO) { … } } // Register the checker that checks for direct accesses in functions annotated // with __attribute__((annotate("objc_no_direct_instance_variable_assignment"))). static bool AttrFilter(const ObjCMethodDecl *M) { … } // Register the checker that checks for direct accesses in all functions, // except for the initialization and copy routines. void ento::registerDirectIvarAssignment(CheckerManager &mgr) { … } bool ento::shouldRegisterDirectIvarAssignment(const CheckerManager &mgr) { … }