diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp @@ -15,25 +15,24 @@ namespace clang::tidy::cppcoreguidelines { -namespace { -AST_MATCHER(VarDecl, isLocalVarDecl) { return Node.isLocalVarDecl(); } -} // namespace - void AvoidNonConstGlobalVariablesCheck::registerMatchers(MatchFinder *Finder) { + auto GlobalContext = + varDecl(hasGlobalStorage(), + hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl()))); + auto GlobalVariable = varDecl( - hasGlobalStorage(), + GlobalContext, unless(anyOf( - isLocalVarDecl(), isConstexpr(), hasType(isConstQualified()), + isConstexpr(), hasType(isConstQualified()), hasType(referenceType())))); // References can't be changed, only the // data they reference can be changed. auto GlobalReferenceToNonConst = - varDecl(hasGlobalStorage(), hasType(referenceType()), + varDecl(GlobalContext, hasType(referenceType()), unless(hasType(references(qualType(isConstQualified()))))); - auto GlobalPointerToNonConst = - varDecl(hasGlobalStorage(), - hasType(pointerType(pointee(unless(isConstQualified()))))); + auto GlobalPointerToNonConst = varDecl( + GlobalContext, hasType(pointerType(pointee(unless(isConstQualified()))))); Finder->addMatcher(GlobalVariable.bind("non-const_variable"), this); Finder->addMatcher(GlobalReferenceToNonConst.bind("indirection_to_non-const"), diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -163,6 +163,11 @@ `, so that it does not warn on macros starting with underscore and lowercase letter. +- Improved :doc:`cppcoreguidelines-avoid-non-const-global-variables + ` check + to ignore ``static`` variables declared within the scope of + ``class``/``struct``. + - Improved :doc:`llvm-namespace-comment ` check to provide fixes for ``inline`` namespaces in the same format as :program:`clang-format`. diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-non-const-global-variables.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-non-const-global-variables.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-non-const-global-variables.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-non-const-global-variables.cpp @@ -236,3 +236,17 @@ nonConstInt = nonConstLoopVariable + i + staticNonConstLoopVariable; } } + +// CHECKING AGAINST FALSE POSITIVES INSIDE STRUCT SCOPE ///////////////////// +struct StructWithStatic { + static DummyStruct nonConstDummyStructInstance; + static int value; + static int* valuePtr; + static int& valueRef; +}; + +DummyStruct StructWithStatic::nonConstDummyStructInstance; +int StructWithStatic::value = 0; +int* StructWithStatic::valuePtr = &StructWithStatic::value; +int& StructWithStatic::valueRef = StructWithStatic::value; +