[clang-tidy] Adds `IgnoreMacros` option to cppcoreguidelines-avoid-non-const-global-variables (#198183) Adds `IgnoreMacros` option to [cppcoreguidelines-avoid-non-const-global-variables](https://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/avoid-non-const-global-variables.html) GitOrigin-RevId: c0539034f37048dd534eff70486a86998f6cfb18
diff --git a/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp b/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp index 2c0baa5..7f5e27d 100644 --- a/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp +++ b/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp
@@ -18,7 +18,8 @@ StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), AllowInternalLinkage(Options.get("AllowInternalLinkage", false)), - AllowThreadLocal(Options.get("AllowThreadLocal", false)) {} + AllowThreadLocal(Options.get("AllowThreadLocal", false)), + IgnoreMacros(Options.get("IgnoreMacros", false)) {} void AvoidNonConstGlobalVariablesCheck::registerMatchers(MatchFinder *Finder) { auto NamespaceMatcher = AllowInternalLinkage @@ -57,8 +58,12 @@ const MatchFinder::MatchResult &Result) { if (const auto *Variable = Result.Nodes.getNodeAs<VarDecl>("non-const_variable")) { - diag(Variable->getLocation(), "variable %0 is non-const and globally " - "accessible, consider making it const") + const SourceLocation Loc = Variable->getLocation(); + if (IgnoreMacros && Loc.isMacroID()) + return; + + diag(Loc, "variable %0 is non-const and globally " + "accessible, consider making it const") << Variable; // FIXME: Add fix-it hint to Variable // Don't return early, a non-const variable may also be a pointer or // reference to non-const data. @@ -66,7 +71,11 @@ if (const auto *VD = Result.Nodes.getNodeAs<VarDecl>("indirection_to_non-const")) { - diag(VD->getLocation(), + const SourceLocation Loc = VD->getLocation(); + if (IgnoreMacros && Loc.isMacroID()) + return; + + diag(Loc, "variable %0 provides global access to a non-const object; consider " "making the %select{referenced|pointed-to}1 data 'const'") << VD @@ -77,6 +86,7 @@ void AvoidNonConstGlobalVariablesCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "AllowInternalLinkage", AllowInternalLinkage); + Options.store(Opts, "IgnoreMacros", IgnoreMacros); } } // namespace clang::tidy::cppcoreguidelines
diff --git a/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.h b/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.h index d8f2a73..9f02082 100644 --- a/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.h +++ b/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.h
@@ -28,6 +28,7 @@ private: const bool AllowInternalLinkage; const bool AllowThreadLocal; + const bool IgnoreMacros; }; } // namespace clang::tidy::cppcoreguidelines
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index b3a2e89..f1b49e2 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst
@@ -447,6 +447,11 @@ lambda coroutines using C++23 deducing ``this`` (explicit object parameter) are not flagged. +- Improved :doc:`cppcoreguidelines-avoid-non-const-global-variables + <clang-tidy/checks/cppcoreguidelines/avoid-non-const-global-variables>` + check by adding the `IgnoreMacros` option. When enabled, non-const global + variables defined in macros are ignored. + - Improved :doc:`cppcoreguidelines-init-variables <clang-tidy/checks/cppcoreguidelines/init-variables>` check by ensuring that member pointers are correctly flagged as uninitialized.
diff --git a/docs/clang-tidy/checks/cppcoreguidelines/avoid-non-const-global-variables.rst b/docs/clang-tidy/checks/cppcoreguidelines/avoid-non-const-global-variables.rst index b7d2dc8..d122685 100644 --- a/docs/clang-tidy/checks/cppcoreguidelines/avoid-non-const-global-variables.rst +++ b/docs/clang-tidy/checks/cppcoreguidelines/avoid-non-const-global-variables.rst
@@ -54,3 +54,8 @@ When set to `true`, non-const global variables with thread-local storage duration will not generate a warning. The default value is `false`. + +.. option:: IgnoreMacros + + When set to `true`, non-const global variables defined in macros will not + generate a warning. The default value is `false`.
diff --git a/test/clang-tidy/checkers/cppcoreguidelines/avoid-non-const-global-variables-macros.cpp b/test/clang-tidy/checkers/cppcoreguidelines/avoid-non-const-global-variables-macros.cpp new file mode 100644 index 0000000..9a099d7 --- /dev/null +++ b/test/clang-tidy/checkers/cppcoreguidelines/avoid-non-const-global-variables-macros.cpp
@@ -0,0 +1,28 @@ +// RUN: %check_clang_tidy %s cppcoreguidelines-avoid-non-const-global-variables %t -- \ +// RUN: -config="{CheckOptions: {cppcoreguidelines-avoid-non-const-global-variables.IgnoreMacros: false}}" +// RUN: %check_clang_tidy %s -check-suffixes=IGNORE-MACROS cppcoreguidelines-avoid-non-const-global-variables %t -- \ +// RUN: -config="{CheckOptions: {cppcoreguidelines-avoid-non-const-global-variables.IgnoreMacros: true}}" + +int nonConstInt = 0; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'nonConstInt' is non-const and globally accessible, consider making it const +// CHECK-MESSAGES-IGNORE-MACROS: :[[@LINE-2]]:5: warning: variable 'nonConstInt' is non-const and globally accessible, consider making it const + +int &nonConstReference = nonConstInt; +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: variable 'nonConstReference' provides global access to a non-const object; consider making the referenced data 'const' +// CHECK-MESSAGES-IGNORE-MACROS: :[[@LINE-2]]:6: warning: variable 'nonConstReference' provides global access to a non-const object; consider making the referenced data 'const' + +#define DEFINE_NON_CONST_INT int macroInt = 0; + +DEFINE_NON_CONST_INT +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: variable 'macroInt' is non-const and globally accessible, consider making it const + +#define DEFINE_NON_CONST_REFERENCE int ¯oRef = nonConstInt; + +DEFINE_NON_CONST_REFERENCE +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: variable 'macroRef' provides global access to a non-const object; consider making the referenced data 'const' + +#define DEFINE_NON_CONST_POINTER int *macroPtr = &nonConstInt; + +DEFINE_NON_CONST_POINTER +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: variable 'macroPtr' is non-const and globally accessible, consider making it const +// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: variable 'macroPtr' provides global access to a non-const object; consider making the pointed-to data 'const'