diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp index e8a2e7b8ef86..e9f0bd98cad1 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp @@ -19,7 +19,7 @@ void InterfacesGlobalInitCheck::registerMatchers(MatchFinder *Finder) { hasDeclContext(anyOf(translationUnitDecl(), // Global scope. namespaceDecl(), // Namespace scope. recordDecl())), // Class scope. - unless(isConstexpr())); + unless(isConstexpr()), unless(isConstinit())); const auto ReferencesUndefinedGlobalVar = declRefExpr(hasDeclaration( varDecl(GlobalVarDecl, unless(isDefinition())).bind("referencee"))); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index afaa04e4083c..cf97ab708247 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -232,6 +232,10 @@ Changes in existing checks ` check by adding the option `IgnoreMacros` to ignore ``goto`` labels defined in macros. +- Improved :doc:`cppcoreguidelines-interfaces-global-init + ` check by + fixing false positives on uses of ``constinit`` variables. + - Improved :doc:`cppcoreguidelines-missing-std-forward ` check by adding a flag to specify the function used for forwarding instead of ``std::forward``. diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/interfaces-global-init.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/interfaces-global-init.cpp index 51f79e522c0c..8ce42994e117 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/interfaces-global-init.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/interfaces-global-init.cpp @@ -14,11 +14,23 @@ static int GlobalScopeBadInit3 = takesIntPtr(&ExternGlobal); static int GlobalScopeBadInit4 = 3 * (ExternGlobal + 2); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal' +#if __cplusplus >= 202002L +extern constinit int ExternConstinitGlobal; +static int GlobalScopeConstinit1 = ExternConstinitGlobal; +static int GlobalScopeConstinit2 = takesInt(ExternConstinitGlobal); +static int GlobalScopeConstinit3 = takesIntPtr(&ExternConstinitGlobal); +static int GlobalScopeConstinit4 = 3 * (ExternConstinitGlobal + 2); +#endif + namespace ns { static int NamespaceScope = makesInt(); static int NamespaceScopeBadInit = takesInt(ExternGlobal); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal' +#if __cplusplus >= 202002L +static int NamespaceScopeConstinit = takesInt(ExternConstinitGlobal); +#endif + struct A { static int ClassScope; static int ClassScopeBadInit; @@ -29,6 +41,17 @@ int A::ClassScopeBadInit = takesInt(ExternGlobal); static int FromClassBadInit = takesInt(A::ClassScope); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ClassScope' + +#if __cplusplus >= 202002L +struct B { + static constinit int ClassScopeConstinit; + static int ClassScopeFromConstinit; +}; + +int B::ClassScopeFromConstinit = takesInt(ExternConstinitGlobal); +static int FromClassScopeConstinit = takesInt(B::ClassScopeConstinit); +#endif + } // namespace ns // "const int B::I;" is fine, it just ODR-defines B::I. See [9.4.3] Static @@ -42,6 +65,16 @@ const int B1::J; // CHECK-MESSAGES: [[@LINE-1]]:15: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'I' const int B1::I; +#if __cplusplus >= 202002L +class D { + static const constinit int I = 0; + static const int J = I; +}; + +const int D::J; +const int D::I; +#endif + void f() { // This is fine, it's executed after dynamic initialization occurs. static int G = takesInt(ExternGlobal); @@ -81,4 +114,3 @@ class B2 { }; const int B2::I; const int B2::J; -