tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GlobalVariableInitializationChecker.cpp (2837B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "GlobalVariableInitializationChecker.h"
      6 #include "CustomMatchers.h"
      7 
      8 void GlobalVariableInitializationChecker::registerMatchers(MatchFinder *AstMatcher) {
      9  auto FirstPartyGlobalVariable = varDecl(
     10      hasGlobalStorage(),
     11      unless(hasDeclContext(functionDecl())),
     12      allOf(isDefinition(), isFirstParty(), unless(isExpansionInSystemHeader()))
     13  );
     14 
     15  auto FirstPartyGlobalVariableWithRuntimeInit = varDecl(FirstPartyGlobalVariable,
     16      allOf(anyOf(isConstexpr(), hasConstInitAttr(), hasConstantInitializer(), hasMozGlobalType()), isMozGlobal()),
     17      unless(isMozGenerated())
     18      );
     19 
     20  AstMatcher->addMatcher(FirstPartyGlobalVariableWithRuntimeInit.bind("flagged-constinit_global"), this);
     21 
     22  auto FirstPartyGlobalVariableWithoutAnnotation = varDecl(
     23      FirstPartyGlobalVariable,
     24      unless(anyOf(isConstexpr(), hasConstInitAttr(), isMozGlobal(), hasConstantInitializer(), hasMozGlobalType()))
     25      );
     26 
     27  AstMatcher->addMatcher(FirstPartyGlobalVariableWithoutAnnotation.bind("non-constinit_global"), this);
     28 }
     29 
     30 void GlobalVariableInitializationChecker::check(
     31    const MatchFinder::MatchResult &Result) {
     32  if (const VarDecl *VD =
     33          Result.Nodes.getNodeAs<VarDecl>("flagged-constinit_global")) {
     34    if (VD->hasConstantInitialization()) {
     35      diag(VD->getBeginLoc(), "Global variable flagged as MOZ_RUNINIT but actually has constinit initialisation. Consider flagging it as constexpr or constinit instead.",
     36           DiagnosticIDs::Error);
     37    }
     38    else {
     39      diag(VD->getBeginLoc(), "Global variable flagged as MOZ_RUNINIT but actually has constant initialisation. Consider removing the annotation or (as a last resort) flagging it as MOZ_GLOBINIT.",
     40           DiagnosticIDs::Error);
     41    }
     42  }
     43 
     44  if (const VarDecl *VD =
     45          Result.Nodes.getNodeAs<VarDecl>("non-constinit_global")) {
     46    const SourceManager &SM = VD->getASTContext().getSourceManager();
     47 
     48    SourceLocation Loc = VD->getLocation();
     49 
     50    // Some macro from third party end up triggering warning, we can't fix that
     51    // easily so ignore them.
     52    if (SM.isMacroBodyExpansion(Loc))
     53      return;
     54 
     55    // FIXME: This captures some generated third party source, e.g. from
     56    // google-protocol, that are generated by third-party generators but are not
     57    // captured by `isFirstParty`, but may also catch some sources we own.
     58    if (getFilename(SM, Loc).ends_with(".cc")) {
     59      return;
     60    }
     61    diag(VD->getBeginLoc(), "Global variable has runtime initialisation, try to remove it, make it constexpr or constinit if possible, or as a last resort flag it as MOZ_RUNINIT.",
     62         DiagnosticIDs::Error);
     63  }
     64 }