https://github.com/localspook updated 
https://github.com/llvm/llvm-project/pull/148334

>From e6b9c9ab548986d26fe24a91ab360e7c0363817d Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <chernyakin.victo...@outlook.com>
Date: Fri, 11 Jul 2025 21:09:22 -0700
Subject: [PATCH 1/2] [clang-tidy] Teach
 `cppcoreguidelines-interfaces-global-init` about `constinit`

---
 .../InterfacesGlobalInitCheck.cpp             |  2 +-
 clang-tools-extra/docs/ReleaseNotes.rst       |  4 +++
 .../interfaces-global-init.cpp                | 28 +++++++++++++++++--
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp
index e8a2e7b8ef86d..e9f0bd98cad16 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 ad869265a2db5..bff7cfa4fe525 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -212,6 +212,10 @@ Changes in existing checks
   <clang-tidy/checks/cppcoreguidelines/avoid-goto>` check by adding the option
   `IgnoreMacros` to ignore ``goto`` labels defined in macros.
 
+- Improved :doc:`cppcoreguidelines-interfaces-global-init
+  <clang-tidy/checks/cppcoreguidelines/interfaces-global-init>` check by
+  fixing false positives on uses of ``constinit`` variables.
+
 - Improved :doc:`cppcoreguidelines-missing-std-forward
   <clang-tidy/checks/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 51f79e522c0ca..38d02c6a7f186 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
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-interfaces-global-init %t
+// RUN: %check_clang_tidy -std=c++20 %s 
cppcoreguidelines-interfaces-global-init %t
 
 constexpr int makesInt() { return 3; }
 constexpr int takesInt(int i) { return i + 1; }
@@ -14,11 +14,19 @@ 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'
 
+extern constinit int ExternConstinitGlobal;
+static int GlobalScopeConstinit1 = ExternConstinitGlobal;
+static int GlobalScopeConstinit2 = takesInt(ExternConstinitGlobal);
+static int GlobalScopeConstinit3 = takesIntPtr(&ExternConstinitGlobal);
+static int GlobalScopeConstinit4 = 3 * (ExternConstinitGlobal + 2);
+
 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'
 
+static int NamespaceScopeConstinit = takesInt(ExternConstinitGlobal);
+
 struct A {
   static int ClassScope;
   static int ClassScopeBadInit;
@@ -29,6 +37,15 @@ 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'
+
+struct B {
+  static constinit int ClassScopeConstinit;
+  static int ClassScopeFromConstinit;
+};
+
+int B::ClassScopeFromConstinit = takesInt(ExternConstinitGlobal);
+static int FromClassScopeConstinit = takesInt(B::ClassScopeConstinit);
+
 } // namespace ns
 
 // "const int B::I;" is fine, it just ODR-defines B::I. See [9.4.3] Static
@@ -42,6 +59,14 @@ 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;
 
+class D {
+  static const constinit int I = 0;
+  static const int J = I;
+};
+
+const int D::J;
+const int D::I;
+
 void f() {
   // This is fine, it's executed after dynamic initialization occurs.
   static int G = takesInt(ExternGlobal);
@@ -81,4 +106,3 @@ class B2 {
 };
 const int B2::I;
 const int B2::J;
-

>From 2a30a82c553b7ece9fc005a98c58187a0333b9a8 Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <chernyakin.victo...@outlook.com>
Date: Fri, 11 Jul 2025 23:09:05 -0700
Subject: [PATCH 2/2] Reenable for all modes

---
 .../cppcoreguidelines/interfaces-global-init.cpp       | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

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 38d02c6a7f186..8ce42994e1172 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
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy -std=c++20 %s 
cppcoreguidelines-interfaces-global-init %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-interfaces-global-init %t
 
 constexpr int makesInt() { return 3; }
 constexpr int takesInt(int i) { return i + 1; }
@@ -14,18 +14,22 @@ 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;
@@ -38,6 +42,7 @@ 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;
@@ -45,6 +50,7 @@ struct B {
 
 int B::ClassScopeFromConstinit = takesInt(ExternConstinitGlobal);
 static int FromClassScopeConstinit = takesInt(B::ClassScopeConstinit);
+#endif
 
 } // namespace ns
 
@@ -59,6 +65,7 @@ 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;
@@ -66,6 +73,7 @@ class D {
 
 const int D::J;
 const int D::I;
+#endif
 
 void f() {
   // This is fine, it's executed after dynamic initialization occurs.

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to