build/clang-plugin/NoAddRefReleaseOnReturnChecker.cpp
author Nathan Froyd <froydnj@mozilla.com>
Wed, 03 Apr 2019 00:06:04 +0000
changeset 467750 1b9e5f4b0589a636233affb84666a469a4cc4ef5
parent 444396 538a16d495142178a73e0bdc30f100b43d2fd62b
permissions -rw-r--r--
Bug 1537643 - update cc crate; r=glandium This update from the official sources brings in the changes that we were using glandium's fork for, as well as changes enabling us to tweak more settings on Windows. Differential Revision: https://phabricator.services.mozilla.com/D25888

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "NoAddRefReleaseOnReturnChecker.h"
#include "CustomMatchers.h"

void NoAddRefReleaseOnReturnChecker::registerMatchers(MatchFinder *AstMatcher) {
  // Look for all of the calls to AddRef() or Release()
  AstMatcher->addMatcher(
      memberExpr(isAddRefOrRelease(), hasParent(callExpr())).bind("member"),
      this);
}

void NoAddRefReleaseOnReturnChecker::check(
    const MatchFinder::MatchResult &Result) {
  const MemberExpr *Member = Result.Nodes.getNodeAs<MemberExpr>("member");
  const Expr *Base = IgnoreTrivials(Member->getBase());

  // Check if the call to AddRef() or Release() was made on the result of a call
  // to a MOZ_NO_ADDREF_RELEASE_ON_RETURN function or method.
  if (auto *Call = dyn_cast<CallExpr>(Base)) {
    if (auto *Callee = Call->getDirectCallee()) {
      if (hasCustomAttribute<moz_no_addref_release_on_return>(Callee)) {
        diag(Call->getBeginLoc(),
             "%1 cannot be called on the return value of %0",
             DiagnosticIDs::Error)
            << Callee << dyn_cast<CXXMethodDecl>(Member->getMemberDecl());
      }
    }
  }
}