[clang-tools-extra] 65ba527 - [clang-tidy] Support C++20 constinit in bugprone-dynamic-static-initializers (#174744)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 9 20:57:19 PST 2026
Author: mitchell
Date: 2026-01-10T12:57:11+08:00
New Revision: 65ba5276e79f774b07fbdd9398236fc2c5965b50
URL: https://github.com/llvm/llvm-project/commit/65ba5276e79f774b07fbdd9398236fc2c5965b50
DIFF: https://github.com/llvm/llvm-project/commit/65ba5276e79f774b07fbdd9398236fc2c5965b50.diff
LOG: [clang-tidy] Support C++20 constinit in bugprone-dynamic-static-initializers (#174744)
Variables marked with `constinit` are guaranteed to be statically
initialized. This patch add support for these.
Added:
clang-tools-extra/test/clang-tidy/checkers/bugprone/dynamic-static-initializers-constinit.hpp
Modified:
clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/test/clang-tidy/checkers/bugprone/dynamic-static-initializers.hpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp
index d00c8d0ffb925..d40662ab0e7ad 100644
--- a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp
@@ -18,7 +18,10 @@ namespace clang::tidy::bugprone {
namespace {
AST_MATCHER(clang::VarDecl, hasConstantDeclaration) {
- if (Node.isConstexpr())
+ if (Node.isConstexpr() || Node.hasAttr<ConstInitAttr>())
+ return true;
+ if (const VarDecl *Def = Node.getDefinition();
+ Def && (Def->isConstexpr() || Def->hasAttr<ConstInitAttr>()))
return true;
const Expr *Init = Node.getInit();
if (Init && !Init->isValueDependent())
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 76fd1244ea950..d30a7d3549188 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -408,9 +408,12 @@ Changes in existing checks
expansions.
- Improved :doc:`bugprone-dynamic-static-initializers
- <clang-tidy/checks/bugprone/dynamic-static-initializers>` check by
- avoiding false positives for ``constexpr`` variables whose
- initializers are value-dependent.
+ <clang-tidy/checks/bugprone/dynamic-static-initializers>` check:
+
+ - Avoided false positives for ``constexpr`` variables whose initializers
+ are value-dependent.
+
+ - Added support for C++20 ``constinit`` variables.
- Improved :doc:`bugprone-easily-swappable-parameters
<clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/dynamic-static-initializers-constinit.hpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/dynamic-static-initializers-constinit.hpp
new file mode 100644
index 0000000000000..cb7930608f398
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/dynamic-static-initializers-constinit.hpp
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy -std=c++20-or-later %s bugprone-dynamic-static-initializers %t -- -- -fno-threadsafe-statics -fno-delayed-template-parsing
+
+constexpr int const_func() { return 42; }
+
+constinit int a = const_func(); // no warning
+
+constinit int b = 123; // no warning
+
+struct S {
+ static constinit int c;
+};
+constinit int S::c = const_func(); // no warning
+
+int runtime_func() { return 42; }
+
+int e = runtime_func();
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: static variable 'e' may be dynamically initialized in this header file [bugprone-dynamic-static-initializers]
+
+template <typename T>
+struct TemplateS {
+ static constinit int x;
+};
+template <typename T>
+constinit int TemplateS<T>::x = const_func(); // no warning
+
+template <typename T>
+void template_func() {
+ static constinit int v = const_func(); // no warning
+}
+
+void call_template_func() {
+ template_func<int>();
+}
+
+template <int V>
+struct Value {
+ static constinit int v;
+};
+template <int V>
+constinit int Value<V>::v = V; // no warning
+
+thread_local constinit int tl = const_func(); // no warning
+
+struct InlineS {
+ static inline constinit int i = 42; // no warning
+};
+
+auto lambda = []() {
+ static constinit int l = const_func(); // no warning
+ return l;
+};
+
+struct Separate {
+ static constinit int s;
+};
+constinit int Separate::s = 100; // no warning
+
+extern int late_constinit;
+constinit int late_constinit = 42; // no warning
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/dynamic-static-initializers.hpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/dynamic-static-initializers.hpp
index 7a3211512fd84..e0e8a85571e34 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/dynamic-static-initializers.hpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/dynamic-static-initializers.hpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s bugprone-dynamic-static-initializers %t -- -- -fno-threadsafe-statics
+// RUN: %check_clang_tidy %s bugprone-dynamic-static-initializers %t -- -- -fno-threadsafe-statics -fno-delayed-template-parsing
int fact(int n) {
return (n == 0) ? 1 : n * fact(n - 1);
@@ -63,3 +63,6 @@ struct TemplateStruct {
template <typename T>
constexpr T kGlobalMin{std::numeric_limits<T>::min()}; // no warning
+
+extern const int late_constexpr;
+constexpr int late_constexpr = 42; // no warning
More information about the cfe-commits
mailing list