vingeldal updated this revision to Diff 235483.
vingeldal added a comment.
Updating D70265 <https://reviews.llvm.org/D70265>: [clang-tidy] Add clang tidy
check I.2 to cppcoreguidelines
- Adjusted the line breaks of some string literals.
- Modified list.rst
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D70265/new/
https://reviews.llvm.org/D70265
Files:
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.h
clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines-avoid-non-const-global-variables.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-avoid-non-const-global-variables-IgnoreDataMembers.cpp
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-avoid-non-const-global-variables.cpp
Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-avoid-non-const-global-variables.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-avoid-non-const-global-variables.cpp
@@ -0,0 +1,268 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-avoid-non-const-global-variables %t
+
+int nonConstInt = 0;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'nonConstInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+int &nonConstIntReference = nonConstInt;
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: variable 'nonConstIntReference' provides global access to non-const type, consider making the referenced data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+int *pointerToNonConstInt = &nonConstInt;
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: variable 'pointerToNonConstInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: variable 'pointerToNonConstInt' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+int *const constPointerToNonConstInt = &nonConstInt;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'constPointerToNonConstInt' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+namespace namespace_name {
+int nonConstNamespaceInt = 0;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'nonConstNamespaceInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const int constNamespaceInt = 0;
+} // namespace namespace_name
+
+const int constInt = 0;
+
+const int *pointerToConstInt = &constInt;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'pointerToConstInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const int *const constPointerToConstInt = &constInt;
+
+const int &constReferenceToConstInt = constInt;
+
+constexpr int constexprInt = 0;
+
+int function() {
+ int nonConstReturnValue = 0;
+ return nonConstReturnValue;
+}
+
+namespace {
+int nonConstAnonymousNamespaceInt = 0;
+}
+
+class DummyClass {
+public:
+ int nonConstMemberVariable = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: member variable 'nonConstMemberVariable' is globally accessible and non-const, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+ const int constMemberVariable = 0;
+ int *const constMemberPointerToNonConst = &nonConstInt;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: member variable 'constMemberPointerToNonConst' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+ int *memberPointerToNonConst = &nonConstInt;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member variable 'memberPointerToNonConst' is globally accessible and non-const, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+ // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: member variable 'memberPointerToNonConst' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+ const int *const constMemberPointerToConst = &constInt;
+ int &nonConstMemberReferenceToNonConst = nonConstInt;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member variable 'nonConstMemberReferenceToNonConst' is globally accessible and non-const, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+ // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: member variable 'nonConstMemberReferenceToNonConst' provides global access to non-const type, consider making the referenced data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+private:
+ int *privatePointerToNonConst = &nonConstInt;
+ int &privateReferenceToNonConst = nonConstInt;
+ int nonConstPrivateMemberVariable = 0;
+};
+
+class DummyClassWithNonConstStatic {
+public:
+ static int staticNonConstMemberVariable;
+ static const int staticConstMemberVariable;
+
+private:
+ static int staticNonConstPrivateMemberVariable;
+ static const int staticConstPrivateMemberVariable = 0;
+};
+// CHECK-MESSAGES: :[[@LINE-7]]:14: warning: variable 'staticNonConstMemberVariable' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+int DummyClassWithNonConstStatic::staticNonConstMemberVariable = 0;
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: variable 'staticNonConstMemberVariable' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+const int DummyClassWithNonConstStatic::staticConstMemberVariable = 0;
+
+DummyClass nonConstClassInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'nonConstClassInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyClass *pointerToNonConstDummyClass = &nonConstClassInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'pointerToNonConstDummyClass' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+// CHECK-MESSAGES: :[[@LINE-2]]:13: warning: variable 'pointerToNonConstDummyClass' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyClass &referenceToNonConstDummyClass = nonConstClassInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'referenceToNonConstDummyClass' provides global access to non-const type, consider making the referenced data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+int *nonConstPointerToMember = &nonConstClassInstance.nonConstMemberVariable;
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: variable 'nonConstPointerToMember' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: variable 'nonConstPointerToMember' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+int *const constPointerToNonConstMember = &nonConstClassInstance.nonConstMemberVariable;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'constPointerToNonConstMember' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyClass constClassInstance;
+
+DummyClass *const constPointerToNonConstDummyClass = &nonConstClassInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: variable 'constPointerToNonConstDummyClass' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyClass *nonConstPointerToConstDummyClass = &constClassInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: variable 'nonConstPointerToConstDummyClass' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyClass *const constPointerToConstDummyClass = &constClassInstance;
+
+const int *const constPointerToConstMember = &constClassInstance.nonConstMemberVariable;
+
+const DummyClass &constReferenceToDummyClass = constClassInstance;
+
+namespace namespace_name {
+DummyClass nonConstNamespaceClassInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'nonConstNamespaceClassInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyClass constDummyClassInstance;
+} // namespace namespace_name
+
+namespace {
+DummyClass nonConstAnonymousNamespaceClassInstance;
+}
+
+// CHECKING FOR NON-CONST GLOBAL ENUM /////////////////////////////////////////
+enum DummyEnum {
+ first,
+ second
+};
+
+DummyEnum nonConstDummyEnumInstance = DummyEnum::first;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: variable 'nonConstDummyEnumInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyEnum *pointerToNonConstDummyEnum = &nonConstDummyEnumInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'pointerToNonConstDummyEnum' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+// CHECK-MESSAGES: :[[@LINE-2]]:12: warning: variable 'pointerToNonConstDummyEnum' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyEnum &referenceToNonConstDummyEnum = nonConstDummyEnumInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'referenceToNonConstDummyEnum' provides global access to non-const type, consider making the referenced data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyEnum *const constPointerToNonConstDummyEnum = &nonConstDummyEnumInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: variable 'constPointerToNonConstDummyEnum' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyEnum constDummyEnumInstance = DummyEnum::first;
+
+const DummyEnum *nonConstPointerToConstDummyEnum = &constDummyEnumInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: variable 'nonConstPointerToConstDummyEnum' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyEnum *const constPointerToConstDummyEnum = &constDummyEnumInstance;
+
+const DummyEnum &referenceToConstDummyEnum = constDummyEnumInstance;
+
+namespace namespace_name {
+DummyEnum nonConstNamespaceEnumInstance = DummyEnum::first;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: variable 'nonConstNamespaceEnumInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyEnum constNamespaceEnumInstance = DummyEnum::first;
+} // namespace namespace_name
+
+namespace {
+DummyEnum nonConstAnonymousNamespaceEnumInstance = DummyEnum::first;
+}
+
+// CHECKING FOR NON-CONST GLOBAL STRUCT ///////////////////////////////////////
+struct DummyStruct {
+public:
+ int structIntElement = 0;
+ const int constStructIntElement = 0;
+
+private:
+ int privateStructIntElement = 0;
+};
+// CHECK-MESSAGES: :[[@LINE-6]]:7: warning: member variable 'structIntElement' is globally accessible and non-const, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyStruct nonConstDummyStructInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'nonConstDummyStructInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyStruct *pointerToNonConstDummyStruct = &nonConstDummyStructInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: variable 'pointerToNonConstDummyStruct' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+// CHECK-MESSAGES: :[[@LINE-2]]:14: warning: variable 'pointerToNonConstDummyStruct' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyStruct &referenceToNonConstDummyStruct = nonConstDummyStructInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: variable 'referenceToNonConstDummyStruct' provides global access to non-const type, consider making the referenced data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyStruct *const constPointerToNonConstDummyStruct = &nonConstDummyStructInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: variable 'constPointerToNonConstDummyStruct' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyStruct constDummyStructInstance;
+
+const DummyStruct *nonConstPointerToConstDummyStruct = &constDummyStructInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: variable 'nonConstPointerToConstDummyStruct' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyStruct *const constPointerToConstDummyStruct = &constDummyStructInstance;
+
+const DummyStruct &referenceToConstDummyStruct = constDummyStructInstance;
+
+namespace namespace_name {
+DummyStruct nonConstNamespaceDummyStructInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'nonConstNamespaceDummyStructInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyStruct constNamespaceDummyStructInstance;
+} // namespace namespace_name
+
+namespace {
+DummyStruct nonConstAnonymousNamespaceStructInstance;
+}
+
+// CHECKING FOR NON-CONST GLOBAL UNION ////////////////////////////////////////
+union DummyUnion {
+ int unionInteger;
+ char unionChar;
+};
+// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: member variable 'unionInteger' is globally accessible and non-const, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+// CHECK-MESSAGES: :[[@LINE-3]]:8: warning: member variable 'unionChar' is globally accessible and non-const, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyUnion nonConstUnionIntInstance = {0x0};
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'nonConstUnionIntInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyUnion *nonConstPointerToNonConstUnionInt = &nonConstUnionIntInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'nonConstPointerToNonConstUnionInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+// CHECK-MESSAGES: :[[@LINE-2]]:13: warning: variable 'nonConstPointerToNonConstUnionInt' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyUnion *const constPointerToNonConstUnionInt = &nonConstUnionIntInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: variable 'constPointerToNonConstUnionInt' provides global access to non-const type, consider making the pointed-to data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+DummyUnion &referenceToNonConstUnionInt = nonConstUnionIntInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'referenceToNonConstUnionInt' provides global access to non-const type, consider making the referenced data const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyUnion constUnionIntInstance = {0x0};
+
+const DummyUnion *nonConstPointerToConstUnionInt = &constUnionIntInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: variable 'nonConstPointerToConstUnionInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyUnion *const constPointerToConstUnionInt = &constUnionIntInstance;
+
+const DummyUnion &referenceToConstUnionInt = constUnionIntInstance;
+
+namespace namespace_name {
+DummyUnion nonConstNamespaceDummyUnionInstance;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'nonConstNamespaceDummyUnionInstance' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const DummyUnion constNamespaceDummyUnionInstance = {0x0};
+} // namespace namespace_name
+
+namespace {
+DummyUnion nonConstAnonymousNamespaceUnionInstance = {0x0};
+}
+
+// CHECKING FOR NON-CONST GLOBAL FUNCTION POINTER /////////////////////////////
+int dummyFunction() {
+ return 0;
+}
+
+typedef int (*functionPointer)();
+functionPointer fp1 = &dummyFunction;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: variable 'fp1' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+typedef int (*const functionConstPointer)();
+functionPointer fp2 = &dummyFunction;
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: variable 'fp2' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+// CHECKING FOR NON-CONST GLOBAL TEMPLATE VARIABLE ////////////////////////////
+template <class T>
+constexpr T templateVariable = T(0L);
+
+// CHECKING AGAINST FALSE POSITIVES INSIDE FUNCTION SCOPE /////////////////////
+int main() {
+ for (int i = 0; i < 3; ++i) {
+ int nonConstLoopVariable = 42;
+ nonConstInt = nonConstLoopVariable + i;
+ }
+}
Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-avoid-non-const-global-variables-IgnoreDataMembers.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-avoid-non-const-global-variables-IgnoreDataMembers.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-avoid-non-const-global-variables %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: "cppcoreguidelines-avoid-non-const-global-variables.IgnoreDataMembers", \
+// RUN: value: 1}]}' --
+
+int nonConstInt = 0;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'nonConstInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]
+
+const int constInt = 0;
+
+class DummyClass {
+public:
+ int nonConstMemberVariable = 0;
+ const int constMemberVariable = 0;
+ int *const constMemberPointerToNonConst = &nonConstInt;
+ int *memberPointerToNonConst = &nonConstInt;
+ const int *const constMemberPointerToConst = &constInt;
+ int &nonConstMemberReferenceToNonConst = nonConstInt;
+
+private:
+ int *privatePointerToNonConst = &nonConstInt;
+ int &privateReferenceToNonConst = nonConstInt;
+ int nonConstPrivateMemberVariable = 0;
+};
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -370,6 +370,7 @@
`clang-analyzer-unix.cstring.NullArg <clang-analyzer-unix.cstring.NullArg.html>`_, `Clang Static Analyzer <https://clang.llvm.org/docs/analyzer/checkers.html>`_, , ""
`cppcoreguidelines-avoid-c-arrays <cppcoreguidelines-avoid-c-arrays.html>`_, `modernize-avoid-c-arrays <modernize-avoid-c-arrays.html>`_, , "low"
`cppcoreguidelines-avoid-magic-numbers <cppcoreguidelines-avoid-magic-numbers.html>`_, `readability-magic-numbers <readability-magic-numbers.html>`_, , "style"
+ `cppcoreguidelines-avoid-non-const-global-variables <cppcoreguidelines-avoid-non-const-global-variables.html>`_, , , ""
`cppcoreguidelines-c-copy-assignment-signature <cppcoreguidelines-c-copy-assignment-signature.html>`_, `misc-unconventional-assign-operator <misc-unconventional-assign-operator.html>`_, , "medium"
`cppcoreguidelines-explicit-virtual-functions <cppcoreguidelines-explicit-virtual-functions.html>`_, `modernize-use-override <modernize-use-override.html>`_, , "low"
`cppcoreguidelines-non-private-member-variables-in-classes <cppcoreguidelines-non-private-member-variables-in-classes.html>`_, `misc-non-private-member-variables-in-classes <misc-non-private-member-variables-in-classes.html>`_, , "low"
Index: clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines-avoid-non-const-global-variables.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines-avoid-non-const-global-variables.rst
@@ -0,0 +1,54 @@
+.. title:: clang-tidy - cppcoreguidelines-avoid-non-const-global-variables
+
+cppcoreguidelines-avoid-non-const-global-variables
+==================================================
+
+Finds non-const global variables as described in check I.2 of C++ Core
+Guidelines.
+By default this check considers public member variables to be global variables,
+there is an option, ``IgnoreDataMembers``, to turn of checks of member variables.
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Ri-global
+
+.. code-block:: c++
+
+ char a = 0; // Warns!
+ const char b = 0;
+
+ namespace some_namespace
+ {
+ char c = 0; // Warns!
+ const char d = 0;
+ }
+
+ namespace
+ {
+ char e = 0;
+ }
+
+ char * e_ptr1 = &e; // Warns!
+ char *const e_const_ptr // Warns!
+ char & e_reference = e; // Warns!
+
+ class Foo
+ {
+ public:
+ char f = 0; // Warns!
+ const char g = 0;
+ const char * e_ptr2 = &e; // Warns!
+ protected:
+ char h = 0;
+ private:
+ char i = 0;
+ }
+
+Variables: ``a``, ``c``, ``e_ptr1``, ``e_ptr2``, ``e_const_ptr``,
+``e_reference`` and ``f``, will all generate warnings since they are either:
+a globally accessible variable and non-const, a pointer or reference providing
+global access to non-const data or both.
+
+Options
+-------
+
+.. option:: IgnoreDataMembers (default = 0)
+
+ The check will not warn about any member variables if this option is set to 1.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -94,12 +94,18 @@
Without the null terminator it can result in undefined behaviour when the
string is read.
+
- New :doc:`cert-mem57-cpp
<clang-tidy/checks/cert-mem57-cpp>` check.
Checks if an object of type with extended alignment is allocated by using
the default ``operator new``.
+- New :doc:`cppcoreguidelines-avoid-non-const-global-variables
+ <clang-tidy/checks/cppcoreguidelines-avoid-non-const-global-variables>` check.
+ Finds non-const global variables as described in check I.2 of C++ Core
+ Guidelines.
+
- New alias :doc:`cert-pos44-c
<clang-tidy/checks/cert-pos44-c>` to
:doc:`bugprone-bad-signal-to-kill-thread
Index: clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
+++ clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
@@ -15,6 +15,7 @@
#include "../modernize/UseOverrideCheck.h"
#include "../readability/MagicNumbersCheck.h"
#include "AvoidGotoCheck.h"
+#include "AvoidNonConstGlobalVariablesCheck.h"
#include "InitVariablesCheck.h"
#include "InterfacesGlobalInitCheck.h"
#include "MacroUsageCheck.h"
@@ -48,6 +49,8 @@
"cppcoreguidelines-avoid-goto");
CheckFactories.registerCheck<readability::MagicNumbersCheck>(
"cppcoreguidelines-avoid-magic-numbers");
+ CheckFactories.registerCheck<AvoidNonConstGlobalVariablesCheck>(
+ "cppcoreguidelines-avoid-non-const-global-variables");
CheckFactories.registerCheck<modernize::UseOverrideCheck>(
"cppcoreguidelines-explicit-virtual-functions");
CheckFactories.registerCheck<InitVariablesCheck>(
Index: clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
@@ -2,6 +2,7 @@
add_clang_library(clangTidyCppCoreGuidelinesModule
AvoidGotoCheck.cpp
+ AvoidNonConstGlobalVariablesCheck.cpp
CppCoreGuidelinesTidyModule.cpp
InitVariablesCheck.cpp
InterfacesGlobalInitCheck.cpp
Index: clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.h
@@ -0,0 +1,39 @@
+//===--- AvoidNonConstGlobalVariablesCheck.h - clang-tidy -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDNONCONSTGLOBALVARIABLESCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDNONCONSTGLOBALVARIABLESCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace cppcoreguidelines {
+
+/// Non-const global variables hide dependencies and make the dependencies
+/// subject to unpredictable changes.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-avoid-non-const-global-variables.html
+class AvoidNonConstGlobalVariablesCheck : public ClangTidyCheck {
+public:
+ AvoidNonConstGlobalVariablesCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ IgnoreDataMembers(Options.get("IgnoreDataMembers", 0)) {}
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+ const bool IgnoreDataMembers;
+};
+
+} // namespace cppcoreguidelines
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDNONCONSTGLOBALVARIABLESCHECK_H
Index: clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp
@@ -0,0 +1,135 @@
+//===--- AvoidNonConstGlobalVariablesCheck.cpp - clang-tidy ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "AvoidNonConstGlobalVariablesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace cppcoreguidelines {
+
+void AvoidNonConstGlobalVariablesCheck::storeOptions(
+ ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "IgnoreDataMembers", IgnoreDataMembers);
+}
+
+void AvoidNonConstGlobalVariablesCheck::registerMatchers(MatchFinder *Finder) {
+ auto GlobalVariable = varDecl(
+ hasGlobalStorage(),
+ unless(anyOf(
+ isConstexpr(), hasDeclContext(namespaceDecl(isAnonymous())),
+ hasType(isConstQualified()),
+ hasType(referenceType()), // References can't be changed, only the
+ // data they reference can be changed.
+ isPrivate(), // Static member variables are VarDecl, not FieldDecl, so
+ // VarDecl can be private or protected.
+ isProtected())));
+
+ auto GlobalReferenceToNonConst =
+ varDecl(hasGlobalStorage(), hasType(referenceType()),
+ unless(anyOf(hasType(references(qualType(isConstQualified()))),
+ hasDeclContext(namespaceDecl(isAnonymous())))));
+
+ auto GlobalPointerToNonConst =
+ varDecl(hasGlobalStorage(),
+ hasType(pointerType(pointee(unless(isConstQualified())))),
+ unless(hasDeclContext(namespaceDecl(isAnonymous()))));
+
+ auto GlobalMemberVariable = fieldDecl(
+ unless(anyOf(isPrivate(), isProtected(), hasType(isConstQualified()),
+ hasAncestor(namespaceDecl(isAnonymous())))));
+
+ auto GlobalMemberReferenceToNonConst =
+ fieldDecl(hasType(referenceType()),
+ unless(anyOf(hasType(references(qualType(isConstQualified()))),
+ isPrivate(), isProtected(),
+ hasAncestor(namespaceDecl(isAnonymous())))));
+
+ auto GlobalMemberPointerToNonConst =
+ fieldDecl(hasType(pointerType(pointee(unless(isConstQualified())))),
+ unless(anyOf(isPrivate(), isProtected(),
+ hasAncestor(namespaceDecl(isAnonymous())))));
+
+ Finder->addMatcher(GlobalVariable.bind("non-const_variable"), this);
+ Finder->addMatcher(GlobalReferenceToNonConst.bind("reference_to_non-const"),
+ this);
+ Finder->addMatcher(GlobalPointerToNonConst.bind("pointer_to_non-const"),
+ this);
+ Finder->addMatcher(
+ GlobalMemberVariable.bind("non-const_public_member_variable"), this);
+ Finder->addMatcher(
+ GlobalMemberReferenceToNonConst.bind("member_reference_to_non-const"),
+ this);
+ Finder->addMatcher(
+ GlobalMemberPointerToNonConst.bind("member_pointer_to_non-const"), this);
+}
+
+void AvoidNonConstGlobalVariablesCheck::check(
+ 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")
+ << Variable; // FIXME: Add fix-it hint to Variable
+ }
+
+ if (const auto *Reference =
+ Result.Nodes.getNodeAs<VarDecl>("reference_to_non-const")) {
+ diag(Reference->getLocation(),
+ "variable %0 provides global access to non-const type, consider "
+ "making the referenced data const")
+ << Reference; // FIXME: Add fix-it hint to Reference
+ return;
+ }
+
+ if (const auto *Pointer =
+ Result.Nodes.getNodeAs<VarDecl>("pointer_to_non-const")) {
+ diag(Pointer->getLocation(),
+ "variable %0 provides global access to non-const type, consider "
+ "making the pointed-to data const")
+ << Pointer; // FIXME: Add fix-it hint to Pointer
+ return;
+ }
+
+ if (!IgnoreDataMembers) {
+ if (const auto *MemberVariable = Result.Nodes.getNodeAs<FieldDecl>(
+ "non-const_public_member_variable")) {
+ diag(MemberVariable->getLocation(),
+ "member variable %0 is globally accessible and non-const, consider "
+ "making it const")
+ << MemberVariable; // FIXME: Add fix-it hint to MemberVariable
+ }
+
+ if (const auto *MemberReference = Result.Nodes.getNodeAs<FieldDecl>(
+ "member_reference_to_non-const")) {
+ diag(MemberReference->getLocation(),
+ "member variable %0 provides global access to non-const type, "
+ "consider making the referenced data const")
+ << MemberReference; // FIXME: Add fix-it hint to MemberReference
+ return;
+ }
+
+ if (const auto *MemberPointer =
+ Result.Nodes.getNodeAs<FieldDecl>("member_pointer_to_non-const")) {
+ diag(MemberPointer->getLocation(),
+ "member variable %0 provides global access to non-const type, "
+ "consider making the pointed-to data const")
+ << MemberPointer; // FIXME: Add fix-it hint to MemberPointer
+ return;
+ }
+ }
+}
+
+} // namespace cppcoreguidelines
+} // namespace tidy
+} // namespace clang
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits