https://github.com/unterumarmung updated 
https://github.com/llvm/llvm-project/pull/180408

>From 312ae7af727d85acb2c9153bc4d36635a7bb5a5f Mon Sep 17 00:00:00 2001
From: Daniil Dudkin <[email protected]>
Date: Sun, 8 Feb 2026 16:23:22 +0300
Subject: [PATCH] clang-tidy: comment braced-init list arguments

Handle braced-init list arguments in bugprone-argument-comment and\nadd 
coverage for initializer_list and designated initializers.

clang-tidy: gate braced-init argument comments behind options

clang-tidy: split argument-comment init-list tests
---
 .../bugprone/ArgumentCommentCheck.cpp         |  57 ++++++++-
 .../bugprone/ArgumentCommentCheck.h           |   2 +
 clang-tools-extra/docs/ReleaseNotes.rst       |   7 +-
 .../checks/bugprone/argument-comment.rst      |  44 +++++++
 .../bugprone/argument-comment-init-list.cpp   | 108 ++++++++++++++++++
 .../bugprone/argument-comment-literals.cpp    |   3 +-
 6 files changed, 214 insertions(+), 7 deletions(-)
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/bugprone/argument-comment-init-list.cpp

diff --git a/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp
index eb9b710b28549..3e972d6f91fc9 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp
@@ -43,6 +43,9 @@ ArgumentCommentCheck::ArgumentCommentCheck(StringRef Name,
       CommentUserDefinedLiterals(
           Options.get("CommentUserDefinedLiterals", false)),
       CommentCharacterLiterals(Options.get("CommentCharacterLiterals", false)),
+      CommentAnonymousInitLists(
+          Options.get("CommentAnonymousInitLists", false)),
+      CommentTypedInitLists(Options.get("CommentTypedInitLists", false)),
       CommentNullPtrs(Options.get("CommentNullPtrs", false)),
       IdentRE("^(/\\* *)([_A-Za-z][_A-Za-z0-9]*)( *= *\\*/)$") {}
 
@@ -55,6 +58,8 @@ void 
ArgumentCommentCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "CommentStringLiterals", CommentStringLiterals);
   Options.store(Opts, "CommentUserDefinedLiterals", 
CommentUserDefinedLiterals);
   Options.store(Opts, "CommentCharacterLiterals", CommentCharacterLiterals);
+  Options.store(Opts, "CommentAnonymousInitLists", CommentAnonymousInitLists);
+  Options.store(Opts, "CommentTypedInitLists", CommentTypedInitLists);
   Options.store(Opts, "CommentNullPtrs", CommentNullPtrs);
 }
 
@@ -199,14 +204,60 @@ static const FunctionDecl *resolveMocks(const 
FunctionDecl *Func) {
   return Func;
 }
 
+enum class InitListKind {
+  None,
+  Anonymous,
+  Typed,
+};
+
+static InitListKind getInitListKind(const Expr *Arg) {
+  Arg = Arg->IgnoreImplicit();
+
+  if (const auto *StdInit = dyn_cast<CXXStdInitializerListExpr>(Arg))
+    return getInitListKind(StdInit->getSubExpr());
+
+  if (isa<InitListExpr>(Arg))
+    return InitListKind::Anonymous;
+
+  if (const auto *Ctor = dyn_cast<CXXConstructExpr>(Arg)) {
+    if (!Ctor->isListInitialization())
+      return InitListKind::None;
+    // CXXTemporaryObjectExpr corresponds to explicit Type{...} syntax.
+    if (isa<CXXTemporaryObjectExpr>(Ctor))
+      return InitListKind::Typed;
+    // Other list-initialized constructions (for example '{}') have no
+    // explicit type at the call site.
+    return InitListKind::Anonymous;
+  }
+
+  if (const auto *FuncCast = dyn_cast<CXXFunctionalCastExpr>(Arg)) {
+    if (FuncCast->isListInitialization())
+      return InitListKind::Typed;
+  }
+
+  return InitListKind::None;
+}
+
 // Given the argument type and the options determine if we should
 // be adding an argument comment.
 bool ArgumentCommentCheck::shouldAddComment(const Expr *Arg) const {
-  Arg = Arg->IgnoreImpCasts();
-  if (isa<UnaryOperator>(Arg))
-    Arg = cast<UnaryOperator>(Arg)->getSubExpr();
+  // Strip implicit wrappers so brace-init arguments bound to references still
+  // look like list-initialization at this point.
+  Arg = Arg->IgnoreImplicit();
+  if (const auto *UO = dyn_cast<UnaryOperator>(Arg))
+    Arg = UO->getSubExpr()->IgnoreImplicit();
   if (Arg->getExprLoc().isMacroID())
     return false;
+
+  switch (getInitListKind(Arg)) {
+  case InitListKind::Anonymous:
+    return CommentAnonymousInitLists;
+  case InitListKind::Typed:
+    return CommentTypedInitLists;
+  case InitListKind::None:
+    break;
+  }
+
   return (CommentBoolLiterals && isa<CXXBoolLiteralExpr>(Arg)) ||
          (CommentIntegerLiterals && isa<IntegerLiteral>(Arg)) ||
          (CommentFloatLiterals && isa<FloatingLiteral>(Arg)) ||
diff --git a/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.h 
b/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.h
index 30fa32fad72e7..60a1338233f66 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.h
+++ b/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.h
@@ -46,6 +46,8 @@ class ArgumentCommentCheck : public ClangTidyCheck {
   const unsigned CommentStringLiterals : 1;
   const unsigned CommentUserDefinedLiterals : 1;
   const unsigned CommentCharacterLiterals : 1;
+  const unsigned CommentAnonymousInitLists : 1;
+  const unsigned CommentTypedInitLists : 1;
   const unsigned CommentNullPtrs : 1;
   llvm::Regex IdentRE;
 
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 5c0060877a67f..3bd3ec498dcd7 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -146,8 +146,11 @@ Changes in existing checks
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 - Improved :doc:`bugprone-argument-comment
-  <clang-tidy/checks/bugprone/argument-comment>` to also check for C++11
-  inherited constructors.
+  <clang-tidy/checks/bugprone/argument-comment>`:
+  - Also checks for C++11 inherited constructors.
+  - Adds ``CommentAnonymousInitLists`` and ``CommentTypedInitLists`` options
+    to comment braced-init list arguments (for example, ``{}`` and
+    ``Type{}``).
 
 - Improved :doc:`bugprone-bad-signal-to-kill-thread
   <clang-tidy/checks/bugprone/bad-signal-to-kill-thread>` check by fixing false
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/bugprone/argument-comment.rst 
b/clang-tools-extra/docs/clang-tidy/checks/bugprone/argument-comment.rst
index 8770d7224137a..dc028cde2fcc4 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/argument-comment.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/argument-comment.rst
@@ -146,6 +146,50 @@ After:
 
   foo(/*Character=*/'A');
 
+.. option:: CommentAnonymousInitLists
+
+   When `true`, the check will add argument comments in the format
+   ``/*ParameterName=*/`` right before anonymous braced-init list arguments
+   such as ``{}`` and ``{1, 2, 3}``. Default is `false`.
+
+Before:
+
+.. code-block:: c++
+
+  void foo(const std::vector<int> &Dims);
+
+  foo({});
+
+After:
+
+.. code-block:: c++
+
+  void foo(const std::vector<int> &Dims);
+
+  foo(/*Dims=*/{});
+
+.. option:: CommentTypedInitLists
+
+   When `true`, the check will add argument comments in the format
+   ``/*ParameterName=*/`` right before typed braced-init list arguments such
+   as ``Type{}``. Default is `false`.
+
+Before:
+
+.. code-block:: c++
+
+  void foo(const std::vector<int> &Dims);
+
+  foo(std::vector<int>{});
+
+After:
+
+.. code-block:: c++
+
+  void foo(const std::vector<int> &Dims);
+
+  foo(/*Dims=*/std::vector<int>{});
+
 .. option:: CommentUserDefinedLiterals
 
    When `true`, the check will add argument comments in the format
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone/argument-comment-init-list.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/argument-comment-init-list.cpp
new file mode 100644
index 0000000000000..d98695f81fdd0
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/argument-comment-init-list.cpp
@@ -0,0 +1,108 @@
+// RUN: %check_clang_tidy -check-suffix=OFF -std=c++11,c++14,c++17 %s 
bugprone-argument-comment %t
+// RUN: %check_clang_tidy -check-suffix=ANON -std=c++11,c++14,c++17 %s 
bugprone-argument-comment %t -- \
+// RUN:   -config="{CheckOptions: { \
+// RUN:     bugprone-argument-comment.CommentAnonymousInitLists: true}}" --
+// RUN: %check_clang_tidy -check-suffix=TYPED -std=c++11,c++14,c++17 %s 
bugprone-argument-comment %t -- \
+// RUN:   -config="{CheckOptions: { \
+// RUN:     bugprone-argument-comment.CommentTypedInitLists: true}}" --
+// RUN: %check_clang_tidy -check-suffix=BOTH -std=c++11,c++14,c++17 %s 
bugprone-argument-comment %t -- \
+// RUN:   -config="{CheckOptions: { \
+// RUN:     bugprone-argument-comment.CommentAnonymousInitLists: true, \
+// RUN:     bugprone-argument-comment.CommentTypedInitLists: true}}" --
+// RUN: %check_clang_tidy -check-suffixes=BOTH,BOTH-CXX20 -std=c++20-or-later 
%s bugprone-argument-comment %t -- \
+// RUN:   -config="{CheckOptions: { \
+// RUN:     bugprone-argument-comment.CommentAnonymousInitLists: true, \
+// RUN:     bugprone-argument-comment.CommentTypedInitLists: true}}" --
+
+namespace std {
+using size_t = decltype(sizeof(0));
+
+template <typename T>
+class vector {
+public:
+  vector();
+};
+
+template <typename T>
+class initializer_list {
+  const T *Begin;
+  const T *End;
+
+public:
+  initializer_list() : Begin(nullptr), End(nullptr) {}
+  const T *begin() const { return Begin; }
+  const T *end() const { return End; }
+  size_t size() const { return static_cast<size_t>(End - Begin); }
+};
+} // namespace std
+
+namespace GH171842 {
+
+struct T {
+  int value;
+};
+
+struct Agg {
+  int x;
+  int y;
+};
+
+void foo(T some_arg, const std::vector<int> &dims);
+void foo_init_list(T some_arg, std::initializer_list<int> dims);
+void foo_designated(T some_arg, const Agg &dims);
+
+void test_braced_init_list() {
+  T some_arg{0};
+
+  // Mismatched explicit argument comments are validated independently of the
+  // init-list literal comment options.
+  foo(some_arg, /*dim=*/{});
+  // CHECK-MESSAGES-OFF: warning: argument name 'dim' in comment does not 
match parameter name 'dims'
+  // CHECK-FIXES-OFF: foo(some_arg, /*dims=*/{});
+  // CHECK-MESSAGES-ANON: warning: argument name 'dim' in comment does not 
match parameter name 'dims'
+  // CHECK-FIXES-ANON: foo(some_arg, /*dims=*/{});
+  // CHECK-MESSAGES-TYPED: warning: argument name 'dim' in comment does not 
match parameter name 'dims'
+  // CHECK-FIXES-TYPED: foo(some_arg, /*dims=*/{});
+  // CHECK-MESSAGES-BOTH: warning: argument name 'dim' in comment does not 
match parameter name 'dims'
+  // CHECK-FIXES-BOTH: foo(some_arg, /*dims=*/{});
+
+  foo(some_arg, {});
+  // CHECK-FIXES-OFF: foo(some_arg, {});
+  // CHECK-MESSAGES-ANON: [[@LINE-2]]:17: warning: argument comment missing 
for literal argument 'dims' [bugprone-argument-comment]
+  // CHECK-FIXES-ANON: foo(some_arg, /*dims=*/{});
+  // CHECK-FIXES-TYPED: foo(some_arg, {});
+  // CHECK-MESSAGES-BOTH: [[@LINE-5]]:17: warning: argument comment missing 
for literal argument 'dims' [bugprone-argument-comment]
+  // CHECK-FIXES-BOTH: foo(some_arg, /*dims=*/{});
+
+  foo(some_arg, std::vector<int>{});
+  // CHECK-FIXES-OFF: foo(some_arg, std::vector<int>{});
+  // CHECK-FIXES-ANON: foo(some_arg, std::vector<int>{});
+  // CHECK-MESSAGES-TYPED: [[@LINE-3]]:17: warning: argument comment missing 
for literal argument 'dims' [bugprone-argument-comment]
+  // CHECK-FIXES-TYPED: foo(some_arg, /*dims=*/std::vector<int>{});
+  // CHECK-MESSAGES-BOTH: [[@LINE-5]]:17: warning: argument comment missing 
for literal argument 'dims' [bugprone-argument-comment]
+  // CHECK-FIXES-BOTH: foo(some_arg, /*dims=*/std::vector<int>{});
+}
+
+void test_initializer_list() {
+  T some_arg{0};
+
+  foo_init_list(some_arg, {1, 2, 3});
+  // CHECK-FIXES-OFF: foo_init_list(some_arg, {1, 2, 3});
+  // CHECK-MESSAGES-ANON: [[@LINE-2]]:27: warning: argument comment missing 
for literal argument 'dims' [bugprone-argument-comment]
+  // CHECK-FIXES-ANON: foo_init_list(some_arg, /*dims=*/{1, 2, 3});
+  // CHECK-FIXES-TYPED: foo_init_list(some_arg, {1, 2, 3});
+  // CHECK-MESSAGES-BOTH: [[@LINE-5]]:27: warning: argument comment missing 
for literal argument 'dims' [bugprone-argument-comment]
+  // CHECK-FIXES-BOTH: foo_init_list(some_arg, /*dims=*/{1, 2, 3});
+}
+
+#if __cplusplus >= 202002L
+void test_designated_init() {
+  T some_arg{0};
+
+  foo_designated(some_arg, Agg{.x = 1});
+  // CHECK-MESSAGES-BOTH-CXX20: [[@LINE-1]]:28: warning: argument comment 
missing for literal argument 'dims' [bugprone-argument-comment]
+  // CHECK-FIXES-BOTH-CXX20: foo_designated(some_arg, /*dims=*/Agg{.x = 1});
+}
+#endif
+
+} // namespace GH171842
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone/argument-comment-literals.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/argument-comment-literals.cpp
index f03488a14d9f5..870c198f8058f 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone/argument-comment-literals.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/argument-comment-literals.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s bugprone-argument-comment %t -- \
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s bugprone-argument-comment 
%t -- \
 // RUN:   -config="{CheckOptions: { \
 // RUN:     bugprone-argument-comment.CommentBoolLiterals: true, \
 // RUN:     bugprone-argument-comment.CommentIntegerLiterals: true, \
@@ -7,7 +7,6 @@
 // RUN:     bugprone-argument-comment.CommentStringLiterals: true, \
 // RUN:     bugprone-argument-comment.CommentNullPtrs: true, \
 // RUN:     bugprone-argument-comment.CommentCharacterLiterals: true}}" --
-
 struct A {
   void foo(bool abc);
   void foo(bool abc, bool cde);

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

Reply via email to