[clang-tools-extra] [clang-tidy] Fix a crash in bugprone-std-namespace-modification (PR #214704)

via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 7 04:32:34 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tidy

Author: Zeyi Xu (zeyi2)

<details>
<summary>Changes</summary>

Check the namespaces of template argument types directly from their declarations. This avoids querying the AST parent map (since it may not contain lambda closure types) and fixes the crash.

Fixes #<!-- -->213981

---
Full diff: https://github.com/llvm/llvm-project/pull/214704.diff


3 Files Affected:

- (modified) clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp (+15-4) 
- (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4) 
- (added) clang-tools-extra/test/clang-tidy/checkers/bugprone/std-namespace-modification-no-crash.cpp (+10) 


``````````diff
diff --git a/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp
index a623ed690697b..85ea32f3e7b4f 100644
--- a/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp
@@ -34,6 +34,19 @@ AST_POLYMORPHIC_MATCHER_P(
                              Builder) != Args.end();
 }
 
+AST_MATCHER(NamedDecl, isInStdOrPosixNamespace) {
+  for (const DeclContext *DC = Node.getDeclContext(); DC;
+       DC = DC->getParent()) {
+    if (DC->isStdNamespace())
+      return true;
+
+    if (const auto *NS = dyn_cast<NamespaceDecl>(DC);
+        NS && NS->getName() == "posix" && NS->getParent()->isTranslationUnit())
+      return true;
+  }
+  return false;
+}
+
 } // namespace
 
 namespace clang::tidy::bugprone {
@@ -43,10 +56,8 @@ void StdNamespaceModificationCheck::registerMatchers(MatchFinder *Finder) {
       hasDeclContext(namespaceDecl(hasAnyName("std", "posix"),
                                    unless(hasParent(namespaceDecl())))
                          .bind("nmspc"));
-  const auto UserDefinedDecl =
-      namedDecl(anyOf(classTemplateDecl(), tagDecl()),
-                hasAncestor(namespaceDecl(hasAnyName("std", "posix"),
-                                          unless(hasParent(namespaceDecl())))));
+  const auto UserDefinedDecl = namedDecl(anyOf(classTemplateDecl(), tagDecl()),
+                                         isInStdOrPosixNamespace());
   const auto UserDefinedType = qualType(hasUnqualifiedDesugaredType(anyOf(
       tagType(unless(hasDeclaration(UserDefinedDecl))),
       templateSpecializationType(unless(hasDeclaration(UserDefinedDecl))))));
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 0dcf2ea1f21c7..ed462bc7339fc 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -113,6 +113,10 @@ New check aliases
 Changes in existing checks
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+- Fixed a crash in :doc:`bugprone-std-namespace-modification
+  <clang-tidy/checks/bugprone/std-namespace-modification>` when checking
+  lambda closure types used as template arguments.
+
 - Improved :doc:`cppcoreguidelines-pro-type-member-init
   <clang-tidy/checks/cppcoreguidelines/pro-type-member-init>` check by treating
   ``std::array`` the same as built-in arrays when `IgnoreArrays` option is enabled.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/std-namespace-modification-no-crash.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/std-namespace-modification-no-crash.cpp
new file mode 100644
index 0000000000000..7921e8a40605a
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/std-namespace-modification-no-crash.cpp
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy -std=c++20-or-later -expect-clang-tidy-error %s bugprone-std-namespace-modification %t
+
+template <class A, class B> struct O : A, B {};
+template <class T> void f() {
+  auto a = [](auto) {};
+  auto b = [](auto) -> decltype(({ })) {};
+  O(a, b)(T{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: error: member 'operator()' found in multiple base classes of different types
+}
+template void f<int>();

``````````

</details>


https://github.com/llvm/llvm-project/pull/214704


More information about the cfe-commits mailing list