Skip to content

Commit 54fcf3e

Browse files
authored
[clang] Implement P3176R1: The Oxford variadic comma (#117524)
Emit a deprecation warning when a variadic parameter in a parameter-declaration-clause is not preceded by a comma for C++26.
1 parent 8201926 commit 54fcf3e

File tree

7 files changed

+72
-3
lines changed

7 files changed

+72
-3
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ C++2c Feature Support
256256
- Added the ``__builtin_is_within_lifetime`` builtin, which supports
257257
`P2641R4 Checking if a union alternative is active <https://wg21.link/p2641r4>`_
258258

259+
- Implemented `P3176R1 The Oxford variadic comma <https://wg21.link/P3176R1>`_
260+
259261
C++23 Feature Support
260262
^^^^^^^^^^^^^^^^^^^^^
261263
- Removed the restriction to literal types in constexpr functions in C++23 mode.

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
211211
[CXX11CompatDeprecatedWritableStr]>;
212212
def DeprecatedPragma : DiagGroup<"deprecated-pragma">;
213213
def DeprecatedType : DiagGroup<"deprecated-type">;
214+
def DeprecatedMissingCommaVariadicParam : DiagGroup<"deprecated-missing-comma-variadic-parameter">;
214215
// FIXME: Why is DeprecatedImplementations not in this group?
215216
def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
216217
DeprecatedArrayCompare,
@@ -235,7 +236,8 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
235236
DeprecatedType,
236237
DeprecatedVolatile,
237238
DeprecatedWritableStr,
238-
DeprecatedRedundantConstexprStaticDef
239+
DeprecatedRedundantConstexprStaticDef,
240+
DeprecatedMissingCommaVariadicParam
239241
]>,
240242
DiagCategory<"Deprecations">;
241243

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,9 @@ def err_function_scope_depth_exceeded : Error<
413413
"function scope depth exceeded maximum of %0">, DefaultFatal;
414414
def err_missing_comma_before_ellipsis : Error<
415415
"C requires a comma prior to the ellipsis in a variadic function type">;
416+
def warn_deprecated_missing_comma_before_ellipsis : Warning<
417+
"declaration of a variadic function without a comma before '...' is deprecated">,
418+
InGroup<DeprecatedMissingCommaVariadicParam>;
416419
def err_unexpected_typedef_ident : Error<
417420
"unexpected type name %0: expected identifier">;
418421
def warn_cxx98_compat_decltype : Warning<

clang/lib/Parse/ParseDecl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8119,6 +8119,14 @@ void Parser::ParseParameterDeclarationClause(
81198119
}
81208120

81218121
if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) {
8122+
if (getLangOpts().CPlusPlus26) {
8123+
// C++26 [dcl.dcl.fct]p3:
8124+
// A parameter-declaration-clause of the form
8125+
// parameter-list '...' is deprecated.
8126+
Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
8127+
<< FixItHint::CreateInsertion(EllipsisLoc, ", ");
8128+
}
8129+
81228130
if (!getLangOpts().CPlusPlus) {
81238131
// We have ellipsis without a preceding ',', which is ill-formed
81248132
// in C. Complain and provide the fix.

clang/test/CXX/drs/cwg722.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace std {
1414
using nullptr_t = decltype(nullptr);
1515
}
1616

17-
void f(std::nullptr_t...);
17+
void f(std::nullptr_t, ...);
1818
std::nullptr_t g();
1919
void h() {
2020
std::nullptr_t np;
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: %clang_cc1 -std=c++2c -fsyntax-only -fblocks -verify %s
2+
3+
void a(...);
4+
5+
void b(auto...);
6+
void c(auto, ...);
7+
8+
void d(auto......); // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}} \
9+
// expected-warning {{'...' in this location creates a C-style varargs function}} \
10+
// expected-note {{preceding '...' declares a function parameter pack}} \
11+
// expected-note {{insert ',' before '...' to silence this warning}}
12+
void e(auto..., ...);
13+
14+
void f(auto x...); // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
15+
void g(auto x, ...);
16+
17+
void h(auto... x...); // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}} \
18+
// expected-warning {{'...' in this location creates a C-style varargs function}} \
19+
// expected-note {{preceding '...' declares a function parameter pack}} \
20+
// expected-note {{insert ',' before '...' to silence this warning}}
21+
void i(auto... x, ...);
22+
23+
template<class ...Ts>
24+
void j(Ts... t...) {}; // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}} \
25+
// expected-warning {{'...' in this location creates a C-style varargs function}} \
26+
// expected-note {{preceding '...' declares a function parameter pack}} \
27+
// expected-note {{insert ',' before '...' to silence this warning}}
28+
template<class ...Ts>
29+
void k(Ts... t, ...) {}
30+
31+
void l(int...); // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
32+
void m(int, ...);
33+
34+
void n(int x...); // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
35+
void o(int x, ...);
36+
37+
struct S {
38+
void p(this S...) {} // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
39+
};
40+
41+
template<class ...Ts>
42+
void q(Ts......) {} // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}} \
43+
// expected-warning {{'...' in this location creates a C-style varargs function}} \
44+
// expected-note {{preceding '...' declares a function parameter pack}} \
45+
// expected-note {{insert ',' before '...' to silence this warning}}
46+
47+
template<class T>
48+
void r(T...) {} // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
49+
50+
auto type_specifier = (void (*)(int...)) nullptr; // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
51+
52+
auto lambda = [](int...) {}; // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}
53+
54+
auto block = ^(int...){}; // expected-warning {{declaration of a variadic function without a comma before '...' is deprecated}}

clang/www/cxx_status.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ <h2 id="cxx26">C++2c implementation status</h2>
249249
<tr>
250250
<td>The Oxford variadic comma</td>
251251
<td><a href="https://wg21.link/P3176R1">P3176R1</a></td>
252-
<td class="none" align="center">No</td>
252+
<td class="unreleased" align="center">Clang 20</td>
253253
</tr>
254254
</table>
255255
</details>

0 commit comments

Comments
 (0)