File: GlobalVariableInitializationChecker.cpp

package info (click to toggle)
firefox 147.0.4-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,532 kB
  • sloc: cpp: 7,607,356; javascript: 6,533,348; ansic: 3,775,236; python: 1,415,508; xml: 634,561; asm: 438,949; java: 186,241; sh: 62,760; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (64 lines) | stat: -rw-r--r-- 2,845 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/* 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 "GlobalVariableInitializationChecker.h"
#include "CustomMatchers.h"

void GlobalVariableInitializationChecker::registerMatchers(MatchFinder *AstMatcher) {
  auto FirstPartyGlobalVariable = varDecl(
      hasGlobalStorage(),
      unless(hasDeclContext(functionDecl())),
      allOf(isDefinition(), isFirstParty(), unless(isExpansionInSystemHeader()))
  );

  auto FirstPartyGlobalVariableWithRuntimeInit = varDecl(FirstPartyGlobalVariable,
      allOf(anyOf(isConstexpr(), hasConstInitAttr(), hasConstantInitializer(), hasMozGlobalType()), isMozGlobal()),
      unless(isMozGenerated())
      );

  AstMatcher->addMatcher(FirstPartyGlobalVariableWithRuntimeInit.bind("flagged-constinit_global"), this);

  auto FirstPartyGlobalVariableWithoutAnnotation = varDecl(
      FirstPartyGlobalVariable,
      unless(anyOf(isConstexpr(), hasConstInitAttr(), isMozGlobal(), hasConstantInitializer(), hasMozGlobalType()))
      );

  AstMatcher->addMatcher(FirstPartyGlobalVariableWithoutAnnotation.bind("non-constinit_global"), this);
}

void GlobalVariableInitializationChecker::check(
    const MatchFinder::MatchResult &Result) {
  if (const VarDecl *VD =
          Result.Nodes.getNodeAs<VarDecl>("flagged-constinit_global")) {
    if (VD->hasConstantInitialization()) {
      diag(VD->getBeginLoc(), "Global variable flagged as MOZ_RUNINIT but actually has constinit initialisation. Consider flagging it as constexpr or MOZ_CONSTINIT instead.",
           DiagnosticIDs::Error);
    }
    else {
      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.",
           DiagnosticIDs::Error);
    }
  }

  if (const VarDecl *VD =
          Result.Nodes.getNodeAs<VarDecl>("non-constinit_global")) {
    const SourceManager &SM = VD->getASTContext().getSourceManager();

    SourceLocation Loc = VD->getLocation();

    // Some macro from third party end up triggering warning, we can't fix that
    // easily so ignore them.
    if (SM.isMacroBodyExpansion(Loc))
      return;

    // FIXME: This captures some generated third party source, e.g. from
    // google-protocol, that are generated by third-party generators but are not
    // captured by `isFirstParty`, but may also catch some sources we own.
    if (getFilename(SM, Loc).ends_with(".cc")) {
      return;
    }
    diag(VD->getBeginLoc(), "Global variable has runtime initialisation, try to remove it, make it constexpr or MOZ_CONSTINIT if possible, or as a last resort flag it as MOZ_RUNINIT.",
         DiagnosticIDs::Error);
  }
}