[clang] [clang] Implement P3176R1: The Oxford variadic comma (PR #117524)

via cfe-commits cfe-commits at lists.llvm.org
Sun Dec 1 12:19:12 PST 2024


https://github.com/antangelo updated https://github.com/llvm/llvm-project/pull/117524

>From ffcae3a593f1324b5f5495b42bb0ec61a61c2055 Mon Sep 17 00:00:00 2001
From: antangelo <contact at antangelo.com>
Date: Mon, 25 Nov 2024 01:54:26 -0500
Subject: [PATCH 1/5] [clang] Implement P3176R1: The Oxford variadic comma

Emit a warning when a variadic parameter in a
parameter-declaration-clause is not preceded by a comma for C++26.
---
 clang/docs/ReleaseNotes.rst                   |  2 ++
 clang/include/clang/Basic/DiagnosticGroups.td |  4 ++-
 .../clang/Basic/DiagnosticParseKinds.td       |  3 ++
 clang/lib/Parse/ParseDecl.cpp                 |  8 +++++
 clang/test/CXX/drs/cwg722.cpp                 |  2 +-
 .../Parser/cxx2c-oxford-variadic-comma.cpp    | 36 +++++++++++++++++++
 clang/www/cxx_status.html                     |  2 +-
 7 files changed, 54 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Parser/cxx2c-oxford-variadic-comma.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8bd06fadfdc984..b8d5c4201aeaef 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -227,6 +227,8 @@ C++2c Feature Support
 - Added the ``__builtin_is_within_lifetime`` builtin, which supports
   `P2641R4 Checking if a union alternative is active <https://wg21.link/p2641r4>`_
 
+- Implemented `P3176R1 The Oxford variadic comma <https://wg21.link/P3176R1>`_
+
 C++23 Feature Support
 ^^^^^^^^^^^^^^^^^^^^^
 - Removed the restriction to literal types in constexpr functions in C++23 mode.
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index df9bf94b5d0398..7ad8ac0e7a2e46 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -211,6 +211,7 @@ def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
                                       [CXX11CompatDeprecatedWritableStr]>;
 def DeprecatedPragma : DiagGroup<"deprecated-pragma">;
 def DeprecatedType : DiagGroup<"deprecated-type">;
+def DeprecatedMissingCommaVariadicParam : DiagGroup<"deprecated-missing-comma-variadic-parameter">;
 // FIXME: Why is DeprecatedImplementations not in this group?
 def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
                                           DeprecatedArrayCompare,
@@ -235,7 +236,8 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
                                           DeprecatedType,
                                           DeprecatedVolatile,
                                           DeprecatedWritableStr,
-                                          DeprecatedRedundantConstexprStaticDef
+                                          DeprecatedRedundantConstexprStaticDef,
+                                          DeprecatedMissingCommaVariadicParam
                                           ]>,
                  DiagCategory<"Deprecations">;
 
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 77bf08453dea51..7c3961059d1d0d 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -413,6 +413,9 @@ def err_function_scope_depth_exceeded : Error<
   "function scope depth exceeded maximum of %0">, DefaultFatal;
 def err_missing_comma_before_ellipsis : Error<
   "C requires a comma prior to the ellipsis in a variadic function type">;
+def warn_deprecated_missing_comma_before_ellipsis : Warning<
+  "variadic parameters that are not preceded by a comma are deprecated">,
+  InGroup<DeprecatedMissingCommaVariadicParam>;
 def err_unexpected_typedef_ident : Error<
   "unexpected type name %0: expected identifier">;
 def warn_cxx98_compat_decltype : Warning<
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index aa5c2d28d429ac..d28a74662aefe0 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -8119,6 +8119,14 @@ void Parser::ParseParameterDeclarationClause(
     }
 
     if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) {
+      if (getLangOpts().CPlusPlus26) {
+        // C++26 [dcl.dcl.fct]p3:
+        //   A parameter-declaration-clause of the form
+        //   parameter-list '...' is deprecated
+        Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
+            << FixItHint::CreateInsertion(EllipsisLoc, ", ");
+      }
+
       if (!getLangOpts().CPlusPlus) {
         // We have ellipsis without a preceding ',', which is ill-formed
         // in C. Complain and provide the fix.
diff --git a/clang/test/CXX/drs/cwg722.cpp b/clang/test/CXX/drs/cwg722.cpp
index e90d9af360d9d0..6e7d4569c55381 100644
--- a/clang/test/CXX/drs/cwg722.cpp
+++ b/clang/test/CXX/drs/cwg722.cpp
@@ -14,7 +14,7 @@ namespace std {
   using nullptr_t = decltype(nullptr);
 }
 
-void f(std::nullptr_t...);
+void f(std::nullptr_t, ...);
 std::nullptr_t g();
 void h() {
   std::nullptr_t np;
diff --git a/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp b/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp
new file mode 100644
index 00000000000000..dc78dcbb6b074f
--- /dev/null
+++ b/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -std=c++2c -fsyntax-only -verify %s
+
+void a(...);
+
+void b(auto...);
+void c(auto, ...);
+
+void d(auto......); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}} \
+                    // expected-warning {{'...' in this location creates a C-style varargs function}} \
+                    // expected-note {{preceding '...' declares a function parameter pack}} \
+                    // expected-note {{insert ',' before '...' to silence this warning}}
+void e(auto..., ...);
+
+void f(auto x...); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}}
+void g(auto x, ...);
+
+void h(auto... x...); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}} \
+                      // expected-warning {{'...' in this location creates a C-style varargs function}} \
+                      // expected-note {{preceding '...' declares a function parameter pack}} \
+                      // expected-note {{insert ',' before '...' to silence this warning}}
+void i(auto... x, ...);
+
+template<class ...T>
+void j(T... t...); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}} \
+                   // expected-warning {{'...' in this location creates a C-style varargs function}} \
+                   // expected-note {{preceding '...' declares a function parameter pack}} \
+                   // expected-note {{insert ',' before '...' to silence this warning}}
+template<class ...T>
+void k(T... t, ...);
+
+void l(int...); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}}
+void m(int, ...);
+
+void n(int x...); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}}
+void o(int x, ...);
+
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index da01cf6ceab59b..fdb9807b1168c7 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -249,7 +249,7 @@ <h2 id="cxx26">C++2c implementation status</h2>
  <tr>
   <td>The Oxford variadic comma</td>
   <td><a href="https://wg21.link/P3176R1">P3176R1</a></td>
-  <td class="none" align="center">No</td>
+  <td class="unreleased" align="center">Clang 20</td>
  </tr>
 </table>
 </details>

>From 98d249cdf37cf991f41b2c4090bab22cc6dab2c7 Mon Sep 17 00:00:00 2001
From: antangelo <contact at antangelo.com>
Date: Tue, 26 Nov 2024 20:02:59 -0500
Subject: [PATCH 2/5] Change diagnostic warning wording

---
 .../clang/Basic/DiagnosticParseKinds.td       |  2 +-
 .../Parser/cxx2c-oxford-variadic-comma.cpp    | 24 +++++++++----------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 7c3961059d1d0d..9fa8d5901bd0a5 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -414,7 +414,7 @@ def err_function_scope_depth_exceeded : Error<
 def err_missing_comma_before_ellipsis : Error<
   "C requires a comma prior to the ellipsis in a variadic function type">;
 def warn_deprecated_missing_comma_before_ellipsis : Warning<
-  "variadic parameters that are not preceded by a comma are deprecated">,
+  "declaration of a variadic function without a comma before '...' is deprecated">,
   InGroup<DeprecatedMissingCommaVariadicParam>;
 def err_unexpected_typedef_ident : Error<
   "unexpected type name %0: expected identifier">;
diff --git a/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp b/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp
index dc78dcbb6b074f..e8cc9a55acda00 100644
--- a/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp
+++ b/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp
@@ -5,32 +5,32 @@ void a(...);
 void b(auto...);
 void c(auto, ...);
 
-void d(auto......); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}} \
+void d(auto......); // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}} \
                     // expected-warning {{'...' in this location creates a C-style varargs function}} \
                     // expected-note {{preceding '...' declares a function parameter pack}} \
                     // expected-note {{insert ',' before '...' to silence this warning}}
 void e(auto..., ...);
 
-void f(auto x...); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}}
+void f(auto x...); // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
 void g(auto x, ...);
 
-void h(auto... x...); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}} \
+void h(auto... x...); // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}} \
                       // expected-warning {{'...' in this location creates a C-style varargs function}} \
                       // expected-note {{preceding '...' declares a function parameter pack}} \
                       // expected-note {{insert ',' before '...' to silence this warning}}
 void i(auto... x, ...);
 
-template<class ...T>
-void j(T... t...); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}} \
-                   // expected-warning {{'...' in this location creates a C-style varargs function}} \
-                   // expected-note {{preceding '...' declares a function parameter pack}} \
-                   // expected-note {{insert ',' before '...' to silence this warning}}
-template<class ...T>
-void k(T... t, ...);
+template<class ...Ts>
+void j(Ts... t...) {}; // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}} \
+                       // expected-warning {{'...' in this location creates a C-style varargs function}} \
+                       // expected-note {{preceding '...' declares a function parameter pack}} \
+                       // expected-note {{insert ',' before '...' to silence this warning}}
+template<class ...Ts>
+void k(Ts... t, ...) {}
 
-void l(int...); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}}
+void l(int...); // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
 void m(int, ...);
 
-void n(int x...); // expected-warning {{variadic parameters that are not preceded by a comma are deprecated}}
+void n(int x...); // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
 void o(int x, ...);
 

>From 66e7804dda85012adbb24f3cfaa3bb0933ea1acc Mon Sep 17 00:00:00 2001
From: antangelo <contact at antangelo.com>
Date: Tue, 26 Nov 2024 20:03:19 -0500
Subject: [PATCH 3/5] Add additional test cases

---
 clang/test/Parser/cxx2c-oxford-variadic-comma.cpp | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp b/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp
index e8cc9a55acda00..e0dae02b56ea55 100644
--- a/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp
+++ b/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp
@@ -34,3 +34,16 @@ void m(int, ...);
 void n(int x...); // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
 void o(int x, ...);
 
+struct S {
+  void p(this S...) {} // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
+};
+
+template<class ...Ts>
+void q(Ts......) {} // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}} \
+                    // expected-warning {{'...' in this location creates a C-style varargs function}} \
+                    // expected-note {{preceding '...' declares a function parameter pack}} \
+                    // expected-note {{insert ',' before '...' to silence this warning}}
+
+template<class T>
+void r(T...) {} // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
+

>From 425d560cde7d16ea6f906c4c4cb0a9f8df1679c0 Mon Sep 17 00:00:00 2001
From: antangelo <contact at antangelo.com>
Date: Tue, 26 Nov 2024 20:23:28 -0500
Subject: [PATCH 4/5] Update comment to add full-stop

---
 clang/lib/Parse/ParseDecl.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index d28a74662aefe0..937a94b02458c6 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -8122,7 +8122,7 @@ void Parser::ParseParameterDeclarationClause(
       if (getLangOpts().CPlusPlus26) {
         // C++26 [dcl.dcl.fct]p3:
         //   A parameter-declaration-clause of the form
-        //   parameter-list '...' is deprecated
+        //   parameter-list '...' is deprecated.
         Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
             << FixItHint::CreateInsertion(EllipsisLoc, ", ");
       }

>From b0a33c78c58c59224c60f070dd0ab880c2bf18b4 Mon Sep 17 00:00:00 2001
From: antangelo <contact at antangelo.com>
Date: Sun, 1 Dec 2024 15:17:45 -0500
Subject: [PATCH 5/5] Add test cases for type specifiers, lambdas and blocks

---
 clang/test/Parser/cxx2c-oxford-variadic-comma.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp b/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp
index e0dae02b56ea55..b8015b4815b2e2 100644
--- a/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp
+++ b/clang/test/Parser/cxx2c-oxford-variadic-comma.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2c -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++2c -fsyntax-only -fblocks -verify %s
 
 void a(...);
 
@@ -47,3 +47,8 @@ void q(Ts......) {} // expected-warning {{declaration of a variadic function wit
 template<class T>
 void r(T...) {} // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
 
+auto type_specifier = (void (*)(int...)) nullptr; // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
+
+auto lambda = [](int...) {}; // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
+
+auto block = ^(int...){}; // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}



More information about the cfe-commits mailing list