1 // RUN: %check_clang_tidy %s -check-suffixes=,DEFAULT cppcoreguidelines-avoid-non-const-global-variables %t
2 // RUN: %check_clang_tidy %s -check-suffixes=,INTERNAL-LINKAGE cppcoreguidelines-avoid-non-const-global-variables %t -- \
3 // RUN: -config="{CheckOptions: {cppcoreguidelines-avoid-non-const-global-variables.AllowInternalLinkage : 'true'}}"
4 
5 int nonConstInt = 0;
6 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'nonConstInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
7 
8 int &nonConstIntReference = nonConstInt;
9 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: variable 'nonConstIntReference' provides global access to a non-const object; consider making the referenced data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
10 
11 int *pointerToNonConstInt = &nonConstInt;
12 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: variable 'pointerToNonConstInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
13 // CHECK-MESSAGES: :[[@LINE-2]]:6: warning: variable 'pointerToNonConstInt' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
14 
15 int *const constPointerToNonConstInt = &nonConstInt;
16 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'constPointerToNonConstInt' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
17 
18 namespace namespace_name {
19 int nonConstNamespaceInt = 0;
20 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'nonConstNamespaceInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
21 
22 const int constNamespaceInt = 0;
23 } // namespace namespace_name
24 
25 const int constInt = 0;
26 
27 const int *pointerToConstInt = &constInt;
28 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'pointerToConstInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
29 
30 const int *const constPointerToConstInt = &constInt;
31 
32 const int &constReferenceToConstInt = constInt;
33 
34 constexpr int constexprInt = 0;
35 
function()36 int function() {
37   int nonConstReturnValue = 0;
38   return nonConstReturnValue;
39 }
40 
41 namespace {
42 int nonConstAnonymousNamespaceInt = 0;
43 // 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]
44 // 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]
45 } // namespace
46 
47 static int nonConstStaticInt = 0;
48 // 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]
49 // 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]
50 
51 static const int constStaticInt = 0;
52 
53 class DummyClass {
54 public:
55   int nonConstPublicMemberVariable = 0;
56   const int constPublicMemberVariable = 0;
57 
58 private:
59   int nonConstPrivateMemberVariable = 0;
60   const int constPrivateMemberVariable = 0;
61 };
62 
63 DummyClass nonConstClassInstance;
64 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'nonConstClassInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
65 
66 DummyClass *pointerToNonConstDummyClass = &nonConstClassInstance;
67 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'pointerToNonConstDummyClass' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
68 // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: variable 'pointerToNonConstDummyClass' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
69 
70 DummyClass &referenceToNonConstDummyClass = nonConstClassInstance;
71 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'referenceToNonConstDummyClass' provides global access to a non-const object; consider making the referenced data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
72 
73 int *nonConstPointerToMember = &nonConstClassInstance.nonConstPublicMemberVariable;
74 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: variable 'nonConstPointerToMember' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
75 // CHECK-MESSAGES: :[[@LINE-2]]:6: warning: variable 'nonConstPointerToMember' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
76 int *const constPointerToNonConstMember = &nonConstClassInstance.nonConstPublicMemberVariable;
77 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'constPointerToNonConstMember' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
78 
79 const DummyClass constClassInstance;
80 
81 DummyClass *const constPointerToNonConstDummyClass = &nonConstClassInstance;
82 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: variable 'constPointerToNonConstDummyClass' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
83 
84 const DummyClass *nonConstPointerToConstDummyClass = &constClassInstance;
85 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: variable 'nonConstPointerToConstDummyClass' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
86 
87 const DummyClass *const constPointerToConstDummyClass = &constClassInstance;
88 
89 const int *const constPointerToConstMember = &constClassInstance.nonConstPublicMemberVariable;
90 
91 const DummyClass &constReferenceToDummyClass = constClassInstance;
92 
93 namespace namespace_name {
94 DummyClass nonConstNamespaceClassInstance;
95 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'nonConstNamespaceClassInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
96 
97 const DummyClass constDummyClassInstance;
98 } // namespace namespace_name
99 
100 // CHECKING FOR NON-CONST GLOBAL ENUM /////////////////////////////////////////
101 enum DummyEnum {
102   first,
103   second
104 };
105 
106 DummyEnum nonConstDummyEnumInstance = DummyEnum::first;
107 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: variable 'nonConstDummyEnumInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
108 
109 DummyEnum *pointerToNonConstDummyEnum = &nonConstDummyEnumInstance;
110 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'pointerToNonConstDummyEnum' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
111 // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: variable 'pointerToNonConstDummyEnum' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
112 
113 DummyEnum &referenceToNonConstDummyEnum = nonConstDummyEnumInstance;
114 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'referenceToNonConstDummyEnum' provides global access to a non-const object; consider making the referenced data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
115 
116 DummyEnum *const constPointerToNonConstDummyEnum = &nonConstDummyEnumInstance;
117 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: variable 'constPointerToNonConstDummyEnum' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
118 
119 const DummyEnum constDummyEnumInstance = DummyEnum::first;
120 
121 const DummyEnum *nonConstPointerToConstDummyEnum = &constDummyEnumInstance;
122 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: variable 'nonConstPointerToConstDummyEnum' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
123 
124 const DummyEnum *const constPointerToConstDummyEnum = &constDummyEnumInstance;
125 
126 const DummyEnum &referenceToConstDummyEnum = constDummyEnumInstance;
127 
128 namespace namespace_name {
129 DummyEnum nonConstNamespaceEnumInstance = DummyEnum::first;
130 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: variable 'nonConstNamespaceEnumInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
131 
132 const DummyEnum constNamespaceEnumInstance = DummyEnum::first;
133 } // namespace namespace_name
134 
135 namespace {
136 DummyEnum nonConstAnonymousNamespaceEnumInstance = DummyEnum::first;
137 }
138 // 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]
139 // 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]
140 
141 // CHECKING FOR NON-CONST GLOBAL STRUCT ///////////////////////////////////////
142 struct DummyStruct {
143 public:
144   int structIntElement = 0;
145   const int constStructIntElement = 0;
146 
147 private:
148   int privateStructIntElement = 0;
149 };
150 
151 DummyStruct nonConstDummyStructInstance;
152 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'nonConstDummyStructInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
153 
154 DummyStruct *pointerToNonConstDummyStruct = &nonConstDummyStructInstance;
155 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: variable 'pointerToNonConstDummyStruct' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
156 // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: variable 'pointerToNonConstDummyStruct' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
157 
158 DummyStruct &referenceToNonConstDummyStruct = nonConstDummyStructInstance;
159 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: variable 'referenceToNonConstDummyStruct' provides global access to a non-const object; consider making the referenced data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
160 DummyStruct *const constPointerToNonConstDummyStruct = &nonConstDummyStructInstance;
161 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: variable 'constPointerToNonConstDummyStruct' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
162 
163 const DummyStruct constDummyStructInstance;
164 
165 const DummyStruct *nonConstPointerToConstDummyStruct = &constDummyStructInstance;
166 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: variable 'nonConstPointerToConstDummyStruct' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
167 
168 const DummyStruct *const constPointerToConstDummyStruct = &constDummyStructInstance;
169 
170 const DummyStruct &referenceToConstDummyStruct = constDummyStructInstance;
171 
172 namespace namespace_name {
173 DummyStruct nonConstNamespaceDummyStructInstance;
174 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'nonConstNamespaceDummyStructInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
175 
176 const DummyStruct constNamespaceDummyStructInstance;
177 } // namespace namespace_name
178 
179 namespace {
180 DummyStruct nonConstAnonymousNamespaceStructInstance;
181 }
182 // 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]
183 // 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]
184 
185 // CHECKING FOR NON-CONST GLOBAL UNION ////////////////////////////////////////
186 union DummyUnion {
187   int unionInteger;
188   char unionChar;
189 };
190 
191 DummyUnion nonConstUnionIntInstance = {0x0};
192 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'nonConstUnionIntInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
193 
194 DummyUnion *nonConstPointerToNonConstUnionInt = &nonConstUnionIntInstance;
195 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'nonConstPointerToNonConstUnionInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
196 // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: variable 'nonConstPointerToNonConstUnionInt' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
197 
198 DummyUnion *const constPointerToNonConstUnionInt = &nonConstUnionIntInstance;
199 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: variable 'constPointerToNonConstUnionInt' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
200 
201 DummyUnion &referenceToNonConstUnionInt = nonConstUnionIntInstance;
202 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'referenceToNonConstUnionInt' provides global access to a non-const object; consider making the referenced data 'const' [cppcoreguidelines-avoid-non-const-global-variables]
203 
204 const DummyUnion constUnionIntInstance = {0x0};
205 
206 const DummyUnion *nonConstPointerToConstUnionInt = &constUnionIntInstance;
207 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: variable 'nonConstPointerToConstUnionInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
208 
209 const DummyUnion *const constPointerToConstUnionInt = &constUnionIntInstance;
210 
211 const DummyUnion &referenceToConstUnionInt = constUnionIntInstance;
212 
213 namespace namespace_name {
214 DummyUnion nonConstNamespaceDummyUnionInstance;
215 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'nonConstNamespaceDummyUnionInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
216 
217 const DummyUnion constNamespaceDummyUnionInstance = {0x0};
218 } // namespace namespace_name
219 
220 namespace {
221 DummyUnion nonConstAnonymousNamespaceUnionInstance = {0x0};
222 }
223 // 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]
224 // 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]
225 
226 // CHECKING FOR NON-CONST GLOBAL FUNCTION POINTER /////////////////////////////
dummyFunction()227 int dummyFunction() {
228   return 0;
229 }
230 
231 typedef int (*functionPointer)();
232 functionPointer fp1 = &dummyFunction;
233 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: variable 'fp1' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
234 
235 typedef int (*const functionConstPointer)();
236 functionPointer fp2 = &dummyFunction;
237 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: variable 'fp2' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
238 
239 // CHECKING FOR NON-CONST GLOBAL TEMPLATE VARIABLE ////////////////////////////
240 template <class T>
241 constexpr T templateVariable = T(0L);
242 
243 // CHECKING AGAINST FALSE POSITIVES INSIDE FUNCTION SCOPE /////////////////////
main()244 int main() {
245   for (int i = 0; i < 3; ++i) {
246     static int staticNonConstLoopVariable = 42;
247     int nonConstLoopVariable = 42;
248     nonConstInt = nonConstLoopVariable + i + staticNonConstLoopVariable;
249   }
250 }
251 
252 // CHECKING AGAINST FALSE POSITIVES INSIDE STRUCT SCOPE /////////////////////
253 struct StructWithStatic {
254   static DummyStruct nonConstDummyStructInstance;
255   static int value;
256   static int* valuePtr;
257   static int& valueRef;
258 };
259 
260 DummyStruct StructWithStatic::nonConstDummyStructInstance;
261 int StructWithStatic::value = 0;
262 int* StructWithStatic::valuePtr = &StructWithStatic::value;
263 int& StructWithStatic::valueRef = StructWithStatic::value;
264 
265