Skip to content

Commit e65b36c

Browse files
authored
[clang-tidy] Allow thread-local variables in avoid-non-const-global-variables (llvm#164442)
This patch adds an option named `AllowThreadLocal` to the `cppcoreguidelines-avoid-non-const-global-variables` check. When set to true, the option suppresses warnings generated for non-const global variables with thread-local storage duration. By default, the option is set to false.
1 parent 3d2efe7 commit e65b36c

File tree

5 files changed

+29
-1
lines changed

5 files changed

+29
-1
lines changed

clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ namespace clang::tidy::cppcoreguidelines {
1717
AvoidNonConstGlobalVariablesCheck::AvoidNonConstGlobalVariablesCheck(
1818
StringRef Name, ClangTidyContext *Context)
1919
: ClangTidyCheck(Name, Context),
20-
AllowInternalLinkage(Options.get("AllowInternalLinkage", false)) {}
20+
AllowInternalLinkage(Options.get("AllowInternalLinkage", false)),
21+
AllowThreadLocal(Options.get("AllowThreadLocal", false)) {}
2122

2223
void AvoidNonConstGlobalVariablesCheck::registerMatchers(MatchFinder *Finder) {
2324
auto NamespaceMatcher = AllowInternalLinkage
@@ -31,6 +32,8 @@ void AvoidNonConstGlobalVariablesCheck::registerMatchers(MatchFinder *Finder) {
3132
GlobalContext,
3233
AllowInternalLinkage ? varDecl(unless(isStaticStorageClass()))
3334
: varDecl(),
35+
AllowThreadLocal ? varDecl(unless(hasThreadStorageDuration()))
36+
: varDecl(),
3437
unless(anyOf(
3538
isConstexpr(), hasType(isConstQualified()),
3639
hasType(referenceType())))); // References can't be changed, only the

clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class AvoidNonConstGlobalVariablesCheck : public ClangTidyCheck {
2727

2828
private:
2929
const bool AllowInternalLinkage;
30+
const bool AllowThreadLocal;
3031
};
3132

3233
} // namespace clang::tidy::cppcoreguidelines

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,11 @@ Changes in existing checks
331331
an additional matcher that generalizes the copy-and-swap idiom pattern
332332
detection.
333333

334+
- Improved :doc:`cppcoreguidelines-avoid-non-const-global-variables
335+
<clang-tidy/checks/cppcoreguidelines/avoid-non-const-global-variables>` check
336+
by adding a new option `AllowThreadLocal` that suppresses warnings on
337+
non-const global variables with thread-local storage duration.
338+
334339
- Improved :doc:`cppcoreguidelines-init-variables
335340
<clang-tidy/checks/cppcoreguidelines/init-variables>` check by fixing the
336341
insertion location for function pointers with multiple parameters.

clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-non-const-global-variables.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,8 @@ Options
4949

5050
When set to `true`, static non-const variables and variables in anonymous
5151
namespaces will not generate a warning. The default value is `false`.
52+
53+
.. option:: AllowThreadLocal
54+
55+
When set to `true`, non-const global variables with thread-local storage
56+
duration will not generate a warning. The default value is `false`.

clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-non-const-global-variables.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// RUN: %check_clang_tidy %s -check-suffixes=,DEFAULT cppcoreguidelines-avoid-non-const-global-variables %t
22
// RUN: %check_clang_tidy %s -check-suffixes=,INTERNAL-LINKAGE cppcoreguidelines-avoid-non-const-global-variables %t -- \
33
// RUN: -config="{CheckOptions: {cppcoreguidelines-avoid-non-const-global-variables.AllowInternalLinkage : 'true'}}"
4+
// RUN: %check_clang_tidy %s -check-suffixes=,THREAD-LOCAL cppcoreguidelines-avoid-non-const-global-variables %t -- \
5+
// RUN: -config="{CheckOptions: {cppcoreguidelines-avoid-non-const-global-variables.AllowThreadLocal : 'true'}}"
46

57
int nonConstInt = 0;
68
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'nonConstInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
@@ -42,14 +44,23 @@ namespace {
4244
int nonConstAnonymousNamespaceInt = 0;
4345
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:5: warning: variable 'nonConstAnonymousNamespaceInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
4446
// CHECK-MESSAGES-INTERNAL-LINKAGE-NOT: :[[@LINE-2]]:5: warning: variable 'nonConstAnonymousNamespaceInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
47+
// CHECK-MESSAGES-THREAD-LOCAL: :[[@LINE-3]]:5: warning: variable 'nonConstAnonymousNamespaceInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
4548
} // namespace
4649

4750
static int nonConstStaticInt = 0;
4851
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:12: warning: variable 'nonConstStaticInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
4952
// CHECK-MESSAGES-INTERNAL-LINKAGE-NOT: :[[@LINE-2]]:12: warning: variable 'nonConstStaticInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
53+
// CHECK-MESSAGES-THREAD-LOCAL: :[[@LINE-3]]:12: warning: variable 'nonConstStaticInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
5054

5155
static const int constStaticInt = 0;
5256

57+
thread_local int threadLocalInt = 0;
58+
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:18: warning: variable 'threadLocalInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
59+
// CHECK-MESSAGES-INTERNAL-LINKAGE: :[[@LINE-2]]:18: warning: variable 'threadLocalInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
60+
// CHECK-MESSAGES-THREAD-LOCAL-NOT: :[[@LINE-3]]:18: warning: variable 'threadLocalInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
61+
62+
thread_local const int threadLocalConstInt = 0;
63+
5364
class DummyClass {
5465
public:
5566
int nonConstPublicMemberVariable = 0;
@@ -137,6 +148,7 @@ DummyEnum nonConstAnonymousNamespaceEnumInstance = DummyEnum::first;
137148
}
138149
// CHECK-MESSAGES-DEFAULT: :[[@LINE-2]]:11: warning: variable 'nonConstAnonymousNamespaceEnumInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
139150
// CHECK-MESSAGES-INTERNAL-LINKAGE-NOT: :[[@LINE-2]]:11: warning: variable 'nonConstAnonymousNamespaceEnumInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
151+
// CHECK-MESSAGES-THREAD-LOCAL: :[[@LINE-4]]:11: warning: variable 'nonConstAnonymousNamespaceEnumInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
140152

141153
// CHECKING FOR NON-CONST GLOBAL STRUCT ///////////////////////////////////////
142154
struct DummyStruct {
@@ -181,6 +193,7 @@ DummyStruct nonConstAnonymousNamespaceStructInstance;
181193
}
182194
// CHECK-MESSAGES-DEFAULT: :[[@LINE-2]]:13: warning: variable 'nonConstAnonymousNamespaceStructInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
183195
// CHECK-MESSAGES-INTERNAL-LINKAGE-NOT: :[[@LINE-2]]:11: warning: variable 'nonConstAnonymousNamespaceEnumInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
196+
// CHECK-MESSAGES-THREAD-LOCAL: :[[@LINE-4]]:13: warning: variable 'nonConstAnonymousNamespaceStructInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
184197

185198
// CHECKING FOR NON-CONST GLOBAL UNION ////////////////////////////////////////
186199
union DummyUnion {
@@ -222,6 +235,7 @@ DummyUnion nonConstAnonymousNamespaceUnionInstance = {0x0};
222235
}
223236
// CHECK-MESSAGES-DEFAULT: :[[@LINE-2]]:12: warning: variable 'nonConstAnonymousNamespaceUnionInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
224237
// CHECK-MESSAGES-INTERNAL-LINKAGE-NOT: :[[@LINE-3]]:12: warning: variable 'nonConstAnonymousNamespaceUnionInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
238+
// CHECK-MESSAGES-THREAD-LOCAL: :[[@LINE-4]]:12: warning: variable 'nonConstAnonymousNamespaceUnionInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
225239

226240
// CHECKING FOR NON-CONST GLOBAL FUNCTION POINTER /////////////////////////////
227241
int dummyFunction() {

0 commit comments

Comments
 (0)