Verified Commit 380638db authored by serge-sans-paille's avatar serge-sans-paille Committed by ma1
Browse files

Bug 2039238 - Enforce usage of MOZ_EMPTY_BASES r=tsmith

Unlike VS, we're not constrained by legacy behavior and should always
turn this attribute on where it's needed. There's no VS flag for it, but
we can use clang-tidy to detect when it's needed.

It's okay to use that attribute when it has no effect, so don't bother
trying to be smart in dom/bindings/Codegen.py and always add it.

Differential Revision: https://phabricator.services.mozilla.com/D300299
parent b4c7ffb8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ CHECK(JSHandleRootedTypedefChecker, "js-handle-rooted-typedef")
CHECK(KungFuDeathGripChecker, "kungfu-death-grip")
CHECK(KnownLiveChecker, "known-live")
#ifdef TARGET_IS_WINDOWS
CHECK(EmptyBasesChecker, "empty-bases")
CHECK(LoadLibraryUsageChecker, "load-library-usage")
CHECK(FopenUsageChecker, "fopen-usage")
#endif
+1 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include "ExplicitImplicitChecker.h"
#include "ExplicitOperatorBoolChecker.h"
#ifdef TARGET_IS_WINDOWS
#include "EmptyBasesChecker.h"
#include "LoadLibraryUsageChecker.h"
#include "FopenUsageChecker.h"
#endif
+42 −0
Original line number Diff line number Diff line
/* 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 "EmptyBasesChecker.h"
#include "CustomMatchers.h"

namespace clang {
namespace ast_matchers {

AST_MATCHER_P(CXXRecordDecl, emptyBaseCountAtLeast, unsigned, N) {
  unsigned NumEmptyBases = 0;
  for(const auto & Base : Node.bases()) {
    if(const Type* BaseType = Base.getType().getTypePtrOrNull()) {
      if(const CXXRecordDecl*  CRD = BaseType->getAsCXXRecordDecl(); CRD && CRD->isEmpty())
        NumEmptyBases += 1;
    }
  }
  return NumEmptyBases >= N;
}

AST_MATCHER(CXXRecordDecl, hasMozEmptyBasesAttr) {
  return Node.hasAttr<EmptyBasesAttr>();
}

}

}

void EmptyBasesChecker::registerMatchers(MatchFinder *AstMatcher) {
  AstMatcher->addMatcher(
      cxxRecordDecl(isDefinition(), isFirstParty(), emptyBaseCountAtLeast(2), unless(hasMozEmptyBasesAttr()))
          .bind("class"),
      this);
}

void EmptyBasesChecker::check(const MatchFinder::MatchResult &Result) {
  const CXXRecordDecl *Cls = Result.Nodes.getNodeAs<CXXRecordDecl>("class");
    diag(Cls->getBeginLoc(),
        "Missing MOZ_EMPTY_BASES",
        DiagnosticIDs::Error);
}
+24 −0
Original line number Diff line number Diff line
/* 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/. */

#ifndef EmptyBasesChecker_h_
#define EmptyBasesChecker_h_

#include "plugin.h"

class EmptyBasesChecker : public BaseCheck {
public:
  EmptyBasesChecker(StringRef CheckName, ContextType *Context = nullptr)
      : BaseCheck(CheckName, Context), CI(nullptr) {}
  void registerMatchers(MatchFinder *AstMatcher) override;
  void check(const MatchFinder::MatchResult &Result) override;
  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
    return LangOpts.CPlusPlus;
  }

private:
  const CompilerInstance *CI;
};

#endif
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ HOST_SOURCES += [
if CONFIG["OS_ARCH"] == "WINNT":
    HOST_DEFINES["TARGET_IS_WINDOWS"] = True
    HOST_SOURCES += [
        "EmptyBasesChecker.cpp",
        "FopenUsageChecker.cpp",
        "LoadLibraryUsageChecker.cpp",
    ]
Loading