llvm/clang/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp

//===- IvarInvalidationChecker.cpp ------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
//  This checker implements annotation driven invalidation checking. If a class
//  contains a method annotated with 'objc_instance_variable_invalidator',
//  - (void) foo
//           __attribute__((annotate("objc_instance_variable_invalidator")));
//  all the "ivalidatable" instance variables of this class should be
//  invalidated. We call an instance variable ivalidatable if it is an object of
//  a class which contains an invalidation method. There could be multiple
//  methods annotated with such annotations per class, either one can be used
//  to invalidate the ivar. An ivar or property are considered to be
//  invalidated if they are being assigned 'nil' or an invalidation method has
//  been called on them. An invalidation method should either invalidate all
//  the ivars or call another invalidation method (on self).
//
//  Partial invalidor annotation allows to address cases when ivars are
//  invalidated by other methods, which might or might not be called from
//  the invalidation method. The checker checks that each invalidation
//  method and all the partial methods cumulatively invalidate all ivars.
//    __attribute__((annotate("objc_instance_variable_invalidator_partial")));
//
//===----------------------------------------------------------------------===//

#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.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"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"

usingnamespaceclang;
usingnamespaceento;

namespace {
struct ChecksFilter {};

class IvarInvalidationCheckerImpl {};

static bool isInvalidationMethod(const ObjCMethodDecl *M, bool LookForPartial) {}

void IvarInvalidationCheckerImpl::containsInvalidationMethod(
    const ObjCContainerDecl *D, InvalidationInfo &OutInfo, bool Partial) {}

bool IvarInvalidationCheckerImpl::trackIvar(const ObjCIvarDecl *Iv,
                                        IvarSet &TrackedIvars,
                                        const ObjCIvarDecl **FirstIvarDecl) {}

const ObjCIvarDecl *IvarInvalidationCheckerImpl::findPropertyBackingIvar(
                        const ObjCPropertyDecl *Prop,
                        const ObjCInterfaceDecl *InterfaceD,
                        IvarSet &TrackedIvars,
                        const ObjCIvarDecl **FirstIvarDecl) {}

void IvarInvalidationCheckerImpl::printIvar(llvm::raw_svector_ostream &os,
                                      const ObjCIvarDecl *IvarDecl,
                                      const IvarToPropMapTy &IvarToPopertyMap) {}

// Check that the invalidatable interfaces with ivars/properties implement the
// invalidation methods.
void IvarInvalidationCheckerImpl::
visit(const ObjCImplementationDecl *ImplD) const {}

void IvarInvalidationCheckerImpl::reportNoInvalidationMethod(
    CheckerNameRef CheckName, const ObjCIvarDecl *FirstIvarDecl,
    const IvarToPropMapTy &IvarToPopertyMap,
    const ObjCInterfaceDecl *InterfaceD, bool MissingDeclaration) const {}

void IvarInvalidationCheckerImpl::
reportIvarNeedsInvalidation(const ObjCIvarDecl *IvarD,
                            const IvarToPropMapTy &IvarToPopertyMap,
                            const ObjCMethodDecl *MethodD) const {}

void IvarInvalidationCheckerImpl::MethodCrawler::markInvalidated(
    const ObjCIvarDecl *Iv) {}

const Expr *IvarInvalidationCheckerImpl::MethodCrawler::peel(const Expr *E) const {}

void IvarInvalidationCheckerImpl::MethodCrawler::checkObjCIvarRefExpr(
    const ObjCIvarRefExpr *IvarRef) {}

void IvarInvalidationCheckerImpl::MethodCrawler::checkObjCMessageExpr(
    const ObjCMessageExpr *ME) {}

void IvarInvalidationCheckerImpl::MethodCrawler::checkObjCPropertyRefExpr(
    const ObjCPropertyRefExpr *PA) {}

bool IvarInvalidationCheckerImpl::MethodCrawler::isZero(const Expr *E) const {}

void IvarInvalidationCheckerImpl::MethodCrawler::check(const Expr *E) {}

void IvarInvalidationCheckerImpl::MethodCrawler::VisitBinaryOperator(
    const BinaryOperator *BO) {}

void IvarInvalidationCheckerImpl::MethodCrawler::VisitObjCMessageExpr(
  const ObjCMessageExpr *ME) {}
} // end anonymous namespace

// Register the checkers.
namespace {
class IvarInvalidationChecker :
  public Checker<check::ASTDecl<ObjCImplementationDecl> > {};
} // end anonymous namespace

void ento::registerIvarInvalidationModeling(CheckerManager &mgr) {}

bool ento::shouldRegisterIvarInvalidationModeling(const CheckerManager &mgr) {}

#define REGISTER_CHECKER(name)

REGISTER_CHECKER(InstanceVariableInvalidation)
REGISTER_CHECKER(MissingInvalidationMethod)