diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.h new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.h @@ -0,0 +1,35 @@ +//===--- 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) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace cppcoreguidelines +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDNONCONSTGLOBALVARIABLESCHECK_H diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidNonConstGlobalVariablesCheck.cpp @@ -0,0 +1,98 @@ +//===--- 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::registerMatchers(MatchFinder *Finder) { + const auto GlobalVariable = varDecl( + hasGlobalStorage(), + unless(anyOf( + isConstexpr(), hasDeclContext(namespaceDecl(isAnonymous())), + hasType(isConstQualified()), + hasType(referenceType()), // References can't be changed, only data + // they reference can be changed + isPrivate(), // Static member variables are VarDecl, not FieldDecl, so + // VarDecl can be private or protected + isProtected()))); + + const auto GlobalReferenceToNonConst = + varDecl(hasGlobalStorage(), hasType(referenceType()), + unless(anyOf(hasType(references(qualType(isConstQualified()))), + hasDeclContext(namespaceDecl(isAnonymous()))))); + + const auto GlobalPointerToNonConst = + varDecl(hasGlobalStorage(), + hasType(pointerType(pointee(unless(isConstQualified())))), + unless(anyOf(hasType(pointsTo(isConstQualified())), + hasDeclContext(namespaceDecl(isAnonymous()))))); + + const auto GlobalMemberVariable = fieldDecl( + unless(anyOf(isPrivate(), isProtected(), hasType(isConstQualified())))); + + 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); +} + +void AvoidNonConstGlobalVariablesCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *Variable = Result.Nodes.getNodeAs("non-const_variable"); + const auto *Reference = + Result.Nodes.getNodeAs("reference_to_non-const"); + const auto *Pointer = Result.Nodes.getNodeAs("pointer_to_non-const"); + const auto *MemberVariable = + Result.Nodes.getNodeAs("non-const_public_member_variable"); + + if (Variable) { + diag(Variable->getLocation(), "variable %0 is non-const and globally " + "accessible, consider making it const") + << Variable; + } + // FIXME: Add fix-it hint to MatchedVarDecl + + if (Reference) { + 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 MatchedVarDecl + + if (Pointer) { + 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 MatchedVarDecl + + if (MemberVariable) { + diag(MemberVariable->getLocation(), + "member variable %0 is globally accessible and non-const, consider " + "making it const") + << MemberVariable; + } + // FIXME: Add fix-it hint to MatchedMemberVarDecl +} + +} // namespace cppcoreguidelines +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt +++ b/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 diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ b/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( "cppcoreguidelines-avoid-magic-numbers"); + CheckFactories.registerCheck( + "cppcoreguidelines-avoid-non-const-global-variables"); CheckFactories.registerCheck( "cppcoreguidelines-explicit-virtual-functions"); CheckFactories.registerCheck( 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 @@ -94,12 +94,19 @@ Without the null terminator it can result in undefined behaviour when the string is read. + - New :doc:`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 + ` check. + + Finds non-const global variables as described in check I.2 of cpp core + guidelines. + - New alias :doc:`cert-pos44-c ` to :doc:`bugprone-bad-signal-to-kill-thread diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines-avoid-non-const-global-variables.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines-avoid-non-const-global-variables.rst new file mode 100644 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines-avoid-non-const-global-variables.rst @@ -0,0 +1,7 @@ +.. 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 cpp core +guidelines. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -195,6 +195,7 @@ cppcoreguidelines-avoid-c-arrays (redirects to modernize-avoid-c-arrays) cppcoreguidelines-avoid-goto cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) + cppcoreguidelines-avoid-non-const-global-variables cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) cppcoreguidelines-explicit-virtual-functions (redirects to modernize-use-override) cppcoreguidelines-init-variables 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 new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-avoid-non-const-global-variables.cpp @@ -0,0 +1,257 @@ +// 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; + +private: + 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 +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; + } +}