https://github.com/davidmenggx updated 
https://github.com/llvm/llvm-project/pull/209367

>From 969a71708aa62007a8877f443e748a31633babb2 Mon Sep 17 00:00:00 2001
From: David Meng <[email protected]>
Date: Tue, 4 Aug 2026 09:21:37 -0700
Subject: [PATCH 1/2] Fix merge conflicts

---
 .../clang-tidy/readability/CMakeLists.txt     |   1 +
 .../readability/ReadabilityTidyModule.cpp     |   3 +
 .../RedundantZeroInitializerCheck.cpp         |  65 +++++++++
 .../RedundantZeroInitializerCheck.h           |  38 +++++
 clang-tools-extra/docs/ReleaseNotes.rst       |   6 +
 .../docs/clang-tidy/checks/list.md            |   1 +
 .../readability/redundant-zero-initializer.md |  36 +++++
 .../readability/redundant-zero-initializer.c  |  16 ++
 .../redundant-zero-initializer.cpp            | 138 ++++++++++++++++++
 9 files changed, 304 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/readability/RedundantZeroInitializerCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/readability/RedundantZeroInitializerCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/readability/redundant-zero-initializer.md
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.c
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.cpp

diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 8a4b5753de890..11cadf9f39879 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -54,6 +54,7 @@ add_clang_library(clangTidyReadabilityModule STATIC
   RedundantStringCStrCheck.cpp
   RedundantStringInitCheck.cpp
   RedundantTypenameCheck.cpp
+  RedundantZeroInitializerCheck.cpp
   ReferenceToConstructedTemporaryCheck.cpp
   SimplifyBooleanExprCheck.cpp
   SimplifySubscriptExprCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp 
b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index 69b31d6711bcd..0592ae5f1bf60 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -56,6 +56,7 @@
 #include "RedundantStringCStrCheck.h"
 #include "RedundantStringInitCheck.h"
 #include "RedundantTypenameCheck.h"
+#include "RedundantZeroInitializerCheck.h"
 #include "ReferenceToConstructedTemporaryCheck.h"
 #include "SimplifyBooleanExprCheck.h"
 #include "SimplifySubscriptExprCheck.h"
@@ -160,6 +161,8 @@ class ReadabilityModule : public ClangTidyModule {
         "readability-redundant-qualified-alias");
     CheckFactories.registerCheck<RedundantTypenameCheck>(
         "readability-redundant-typename");
+    CheckFactories.registerCheck<RedundantZeroInitializerCheck>(
+        "readability-redundant-zero-initializer");
     CheckFactories.registerCheck<ReferenceToConstructedTemporaryCheck>(
         "readability-reference-to-constructed-temporary");
     CheckFactories.registerCheck<SimplifySubscriptExprCheck>(
diff --git 
a/clang-tools-extra/clang-tidy/readability/RedundantZeroInitializerCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/RedundantZeroInitializerCheck.cpp
new file mode 100644
index 0000000000000..342ee2930995b
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/RedundantZeroInitializerCheck.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RedundantZeroInitializerCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+AST_MATCHER(InitListExpr, isSingleElementBracedList) {
+  return Node.isExplicit() && Node.getNumInits() == 1;
+}
+
+AST_MATCHER(InitListExpr, isInMacro) {
+  return Node.getBeginLoc().isMacroID() || Node.getEndLoc().isMacroID();
+}
+
+AST_MATCHER(InitListExpr, hasScalarArrayType) {
+  const ConstantArrayType *CAT =
+      Finder->getASTContext().getAsConstantArrayType(Node.getType());
+  return CAT && CAT->getElementType()->isScalarType();
+}
+
+// Matches an array type location whose bound is deduced from the initializer
+// (``T a[]``); replacing ``{0}`` with ``{}`` there would change the size.
+AST_MATCHER(ArrayTypeLoc, hasDeducedArrayBound) {
+  return Node.getSizeExpr() == nullptr;
+}
+} // namespace
+
+void RedundantZeroInitializerCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      initListExpr(hasScalarArrayType(), isSingleElementBracedList(),
+                   hasInit(0, 
ignoringParenImpCasts(integerLiteral(equals(0)))),
+                   unless(isInMacro()),
+                   unless(hasAncestor(cxxStdInitializerListExpr())),
+                   unless(hasParent(varDecl(
+                       hasTypeLoc(arrayTypeLoc(hasDeducedArrayBound()))))))
+          .bind("init"),
+      this);
+}
+
+void RedundantZeroInitializerCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *ILE = Result.Nodes.getNodeAs<InitListExpr>("init");
+  const SourceRange Range = ILE->getSourceRange();
+  diag(Range.getBegin(),
+       "redundant zero initializer; replace with empty braces")
+      << FixItHint::CreateReplacement(Range, "{}");
+}
+
+} // namespace clang::tidy::readability
diff --git 
a/clang-tools-extra/clang-tidy/readability/RedundantZeroInitializerCheck.h 
b/clang-tools-extra/clang-tidy/readability/RedundantZeroInitializerCheck.h
new file mode 100644
index 0000000000000..54906c4e07977
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/RedundantZeroInitializerCheck.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTZEROINITIALIZERCHECK_H
+#define 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTZEROINITIALIZERCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::readability {
+
+/// Finds explicit zero initializers of arrays that can be replaced with empty
+/// braces, e.g. ``char a[12] = {0};`` becomes ``char a[12] = {};``.
+///
+/// For the user-facing documentation see:
+/// 
https://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-zero-initializer.html
+class RedundantZeroInitializerCheck : public ClangTidyCheck {
+public:
+  RedundantZeroInitializerCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+    // Empty braces are only valid in C++ and, for C, since C23.
+    return LangOpts.CPlusPlus || LangOpts.C23;
+  }
+  std::optional<TraversalKind> getCheckTraversalKind() const override {
+    return TK_IgnoreUnlessSpelledInSource;
+  }
+};
+
+} // namespace clang::tidy::readability
+
+#endif // 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTZEROINITIALIZERCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 0dcf2ea1f21c7..0ad39617e097f 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -107,6 +107,12 @@ New checks
   Finds calls to ``value_or`` (and alternative spellings ``valueOr``,
   ``ValueOr``) on optional types where the return type is expensive to copy.
 
+- New :doc:`readability-redundant-zero-initializer
+  <clang-tidy/checks/readability/redundant-zero-initializer>` check.
+
+  Finds explicit zero initializers of arrays that can be replaced with empty
+  braces.
+
 New check aliases
 ^^^^^^^^^^^^^^^^^
 
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.md 
b/clang-tools-extra/docs/clang-tidy/checks/list.md
index 12d8a48ee8d86..5dd3d4ddef963 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.md
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.md
@@ -427,6 +427,7 @@ zircon/*
 | {doc}`readability-redundant-string-cstr <readability/redundant-string-cstr>` 
| Yes |
 | {doc}`readability-redundant-string-init <readability/redundant-string-init>` 
| Yes |
 | {doc}`readability-redundant-typename <readability/redundant-typename>` | Yes 
|
+| {doc}`readability-redundant-zero-initializer 
<readability/redundant-zero-initializer>` | Yes |
 | {doc}`readability-reference-to-constructed-temporary 
<readability/reference-to-constructed-temporary>` |  |
 | {doc}`readability-simplify-boolean-expr <readability/simplify-boolean-expr>` 
| Yes |
 | {doc}`readability-simplify-subscript-expr 
<readability/simplify-subscript-expr>` | Yes |
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-zero-initializer.md
 
b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-zero-initializer.md
new file mode 100644
index 0000000000000..88d7b074d27aa
--- /dev/null
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-zero-initializer.md
@@ -0,0 +1,36 @@
+```{title} clang-tidy - readability-redundant-zero-initializer
+```
+
+# readability-redundant-zero-initializer
+
+Finds explicit zero initializers of arrays that can be replaced with empty
+braces.
+
+In C++ and since C23, an empty braced initializer zero-initializes every 
element
+of an array, so an explicit `{0}` is redundant.
+
+```cpp
+char a[12] = {0};
+int b[5] = {0};
+
+// becomes
+
+char a[12] = {};
+int b[5] = {};
+```
+
+The check is only enabled in C++ and in C23 or later.
+
+## Limitations
+
+To keep the fix always safe, the check is intentionally conservative and only
+handles single-element `{0}` initializers of arrays with an explicit bound.
+It does not flag, among others:
+
+- scalars (`int x = {0};`) and class or struct types (`S s = {0};`);
+- arrays whose bound is deduced from the initializer (`char a[] = {0};`),
+  where `{}` would change the deduced size;
+- multi-dimensional arrays (`int m[2][3] = {0};`);
+- initializers with more than one element (`int a[3] = {0, 0};`);
+- zero written as something other than the integer literal `0`, for example
+  `'\0'`, `0.0` or `nullptr`.
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.c
 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.c
new file mode 100644
index 0000000000000..64986a3d53907
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.c
@@ -0,0 +1,16 @@
+// RUN: %check_clang_tidy -std=c90,c99,c11,c17 -check-suffixes=C17 %s 
readability-redundant-zero-initializer %t
+// RUN: %check_clang_tidy -std=c23-or-later -check-suffixes=C23 %s 
readability-redundant-zero-initializer %t
+
+char a[12] = {0};
+// CHECK-MESSAGES-C23: :[[@LINE-1]]:14: warning: redundant zero initializer; 
replace with empty braces [readability-redundant-zero-initializer]
+// CHECK-FIXES-C23: char a[12] = {};
+
+int b[5] = {0};
+// CHECK-MESSAGES-C23: :[[@LINE-1]]:12: warning: redundant zero initializer; 
replace with empty braces
+// CHECK-FIXES-C23: int b[5] = {};
+
+char deduced[] = {0};
+int multiZero[3] = {0, 0};
+int mixed[4] = {0, 5};
+int oneByOne[1][1] = {0};
+char nullChar[4] = {'\0'};
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.cpp
new file mode 100644
index 0000000000000..dd2d0ace4e2aa
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.cpp
@@ -0,0 +1,138 @@
+// RUN: %check_clang_tidy -std=c++98,c++03 %s 
readability-redundant-zero-initializer %t
+// RUN: %check_clang_tidy -std=c++11 -check-suffixes=,CXX11 %s 
readability-redundant-zero-initializer %t
+// RUN: %check_clang_tidy -std=c++14-or-later -check-suffixes=,CXX11 %s 
readability-redundant-zero-initializer %t
+
+char a[12] = {0};
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant zero initializer; 
replace with empty braces [readability-redundant-zero-initializer]
+// CHECK-FIXES: char a[12] = {};
+
+int b[5] = {0};
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant zero initializer; 
replace with empty braces
+// CHECK-FIXES: int b[5] = {};
+
+double d[3] = {0};
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant zero initializer; 
replace with empty braces
+// CHECK-FIXES: double d[3] = {};
+
+void *p[4] = {0};
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant zero initializer; 
replace with empty braces
+// CHECK-FIXES: void *p[4] = {};
+
+const char cq[8] = {0};
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant zero initializer; 
replace with empty braces
+// CHECK-FIXES: const char cq[8] = {};
+
+int spaced[2] = { 0 };
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant zero initializer; 
replace with empty braces
+// CHECK-FIXES: int spaced[2] = {};
+
+int trailingComma[3] = {0,};
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: redundant zero initializer; 
replace with empty braces
+// CHECK-FIXES: int trailingComma[3] = {};
+
+int paren[2] = {(0)};
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: redundant zero initializer; 
replace with empty braces
+// CHECK-FIXES: int paren[2] = {};
+
+double nestedParen[2] = {((0))};
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: redundant zero initializer; 
replace with empty braces
+// CHECK-FIXES: double nestedParen[2] = {};
+
+void localVariables() {
+  int local[4] = {0};
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: redundant zero initializer; 
replace with empty braces
+  // CHECK-FIXES: int local[4] = {};
+  static int staticLocal[2] = {0};
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: redundant zero initializer; 
replace with empty braces
+  // CHECK-FIXES: static int staticLocal[2] = {};
+}
+
+char emptyBraces[12] = {};
+int nonZero[3] = {1};
+int multiZero[3] = {0, 0};
+int mixed[4] = {0, 5};
+int noInit[3];
+
+// Multi-dimensional arrays without inner braces: the single `0` initializes a
+// subobject through brace elision, so there is no written single-element `{0}`
+// list to rewrite.
+int twoD[2][3] = {0};
+int oneByOne[1][1] = {0};
+int rowVector[1][3] = {0};
+int columnVector[3][1] = {0};
+
+// The array bound is deduced from the initializer, `{}` would change the size.
+char deduced[] = {0};
+
+char nullChar[4] = {'\0'};
+double zeroDouble[3] = {0.0};
+
+int scalar = {0};
+
+struct P { int x; int y; };
+P pod = {0};
+
+#if __cplusplus >= 201103L
+
+struct S {
+  char buf[4] = {0};
+  // CHECK-MESSAGES-CXX11: :[[@LINE-1]]:17: warning: redundant zero 
initializer; replace with empty braces
+  // CHECK-FIXES-CXX11: char buf[4] = {};
+};
+
+void *nullPtr[4] = {nullptr};
+
+using Arr = int[2];
+void use(const int (&)[2]);
+void arrayPrvalue() {
+  use(Arr{0});
+  // CHECK-MESSAGES-CXX11: :[[@LINE-1]]:10: warning: redundant zero 
initializer; replace with empty braces
+  // CHECK-FIXES-CXX11: use(Arr{});
+}
+
+// Template instantiations share the pattern's written braces. Rewriting `{0}`
+// in the pattern would break the `templateFn<X>` instantiation, whose element
+// type is not default-constructible, so neither the pattern nor any of its
+// instantiations may be flagged.
+struct X {
+  X(int);
+  X() = delete;
+};
+
+template <class T>
+void templateFn() {
+  T arr[1] = {0};
+}
+
+void instantiate() {
+  templateFn<int>();
+  templateFn<X>();
+}
+
+// The `const T[N]` backing array of a `std::initializer_list` is an element
+// list, so `{0}` (one element) must not become `{}` (an empty list).
+namespace std {
+template <class T> class initializer_list {
+  const T *Data;
+  __SIZE_TYPE__ Size;
+  initializer_list(const T *D, __SIZE_TYPE__ S) : Data(D), Size(S) {}
+
+public:
+  initializer_list() : Data(nullptr), Size(0) {}
+};
+} // namespace std
+
+struct IntList {
+  IntList(std::initializer_list<int>);
+};
+IntList returnsList() { return {0}; }
+IntList variableList = {0};
+#endif
+
+#if __cplusplus >= 201402L
+// An array of a class type with a default member initializer is an aggregate
+// since C++14. `{0}` and `{}` are not equivalent, so it must not be
+// rewritten.
+struct WithDefault { int v = 7; };
+WithDefault wd[2] = {0};
+#endif

>From 4248a938106b01fdc3466cefb51b18d8abb20a87 Mon Sep 17 00:00:00 2001
From: David Meng <[email protected]>
Date: Wed, 5 Aug 2026 06:59:40 -0700
Subject: [PATCH 2/2] Update
 
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.c

Co-authored-by: Baranov Victor <[email protected]>
---
 .../checkers/readability/redundant-zero-initializer.c           | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.c
 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.c
index 64986a3d53907..25618a4dda47f 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.c
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-zero-initializer.c
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy -std=c90,c99,c11,c17 -check-suffixes=C17 %s 
readability-redundant-zero-initializer %t
+// RUN: %check_clang_tidy -std=c17-or-earlier -check-suffixes=C17 %s 
readability-redundant-zero-initializer %t
 // RUN: %check_clang_tidy -std=c23-or-later -check-suffixes=C23 %s 
readability-redundant-zero-initializer %t
 
 char a[12] = {0};

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to