[clang-tools-extra] [clang-tidy] Fix false positive in `bugprone-std-namespace-modification` when opening subnamespaces of `std::` (PR #174170)
Victor Chernyakin via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 1 17:05:33 PST 2026
https://github.com/localspook created https://github.com/llvm/llvm-project/pull/174170
Adding new subnamespaces to `std` is a no-no, but opening existing ones like `std::ranges` is perfectly fine.
This is the first of a series of changes to improve `bugprone-std-namespace-modification`.
>From 791e8bbbf21402ac22461b1f6650bc1b7eb24b59 Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <chernyakin.victor.j at outlook.com>
Date: Thu, 1 Jan 2026 16:55:17 -0800
Subject: [PATCH] [clang-tidy] Don't diagnose simply opening a namespace like
`std::chrono` in `std-namespace-modification`
---
.../bugprone/StdNamespaceModificationCheck.cpp | 18 ++++++++++--------
clang-tools-extra/docs/ReleaseNotes.rst | 6 ++++++
.../Inputs/Headers/system-header-simulation.h | 8 ++++++++
.../bugprone/std-namespace-modification.cpp | 12 ++++++++++++
4 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp
index 1dff741be3c08..0f4af3b8ab8a8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp
@@ -7,12 +7,12 @@
//===----------------------------------------------------------------------===//
#include "StdNamespaceModificationCheck.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
-using namespace clang;
using namespace clang::ast_matchers;
+namespace clang::tidy::bugprone {
+
namespace {
AST_POLYMORPHIC_MATCHER_P(
@@ -34,9 +34,9 @@ AST_POLYMORPHIC_MATCHER_P(
Builder) != Args.end();
}
-} // namespace
+AST_MATCHER(Decl, isRedecl) { return !Node.isFirstDecl(); }
-namespace clang::tidy::bugprone {
+} // namespace
void StdNamespaceModificationCheck::registerMatchers(MatchFinder *Finder) {
auto HasStdParent =
@@ -76,7 +76,8 @@ void StdNamespaceModificationCheck::registerMatchers(MatchFinder *Finder) {
auto BadNonTemplateSpecializationDecl =
decl(unless(anyOf(functionDecl(isExplicitTemplateSpecialization()),
varDecl(isExplicitTemplateSpecialization()),
- cxxRecordDecl(isExplicitTemplateSpecialization()))),
+ cxxRecordDecl(isExplicitTemplateSpecialization()),
+ namespaceDecl(isRedecl()))),
HasStdParent);
auto BadClassTemplateSpec = classTemplateSpecializationDecl(
HasNoProgramDefinedTemplateArgument, HasStdParent);
@@ -96,7 +97,6 @@ void StdNamespaceModificationCheck::registerMatchers(MatchFinder *Finder) {
.bind("decl"),
this);
}
-} // namespace clang::tidy::bugprone
static const NamespaceDecl *getTopLevelLexicalNamespaceDecl(const Decl *D) {
const NamespaceDecl *LastNS = nullptr;
@@ -108,7 +108,7 @@ static const NamespaceDecl *getTopLevelLexicalNamespaceDecl(const Decl *D) {
return LastNS;
}
-void clang::tidy::bugprone::StdNamespaceModificationCheck::check(
+void StdNamespaceModificationCheck::check(
const MatchFinder::MatchResult &Result) {
const auto *D = Result.Nodes.getNodeAs<Decl>("decl");
const auto *NS = Result.Nodes.getNodeAs<NamespaceDecl>("nmspc");
@@ -127,3 +127,5 @@ void clang::tidy::bugprone::StdNamespaceModificationCheck::check(
<< LexNS;
}
}
+
+} // namespace clang::tidy::bugprone
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 86bfd1d489898..c61392eb7927b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -413,6 +413,12 @@ Changes in existing checks
<clang-tidy/checks/bugprone/sizeof-expression>` check by fixing
a crash on ``sizeof`` of an array of dependent type.
+- Improved :doc:`bugprone-std-namespace-modification
+ <clang-tidy/checks/bugprone/std-namespace-modification>`. It now:
+
+ - No longer diagnoses simply opening subnamespaces of ``std::``
+ such as ``std::chrono``.
+
- Improved :doc:`bugprone-suspicious-include
<clang-tidy/checks/bugprone/suspicious-include>` check by adding
`IgnoredRegex` option.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/system-header-simulation.h b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/system-header-simulation.h
index 0870f60eaa39b..f66d0f7604045 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/system-header-simulation.h
+++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/system-header-simulation.h
@@ -56,6 +56,14 @@ namespace detail {
struct X {};
} // namespace detail
+
+namespace ranges {
+
+template <typename T>
+inline constexpr bool enable_view = false;
+
+} // namespace ranges
+
} // namespace std
// Template specializations that are in a system-header file.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/std-namespace-modification.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/std-namespace-modification.cpp
index 32bcbcaa21c0d..a247ff2915c6c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/std-namespace-modification.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/std-namespace-modification.cpp
@@ -281,3 +281,15 @@ template<typename> struct T {};
T<B> b;
}
+
+struct MyView {};
+
+namespace std::ranges {
+
+template<> constexpr bool enable_view<MyView> = true;
+
+} // namespace std::ranges
+
+struct MyOtherView {};
+
+template<> constexpr bool std::ranges::enable_view<MyOtherView> = true;
More information about the cfe-commits
mailing list