https://github.com/AaronBallman created https://github.com/llvm/llvm-project/pull/115313
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3344.pdf This paper disallows a single `void` parameter from having qualifiers or storage class specifiers. Clang has diagnosed most of these as an error for a long time, but `register void` was previously accepted in all C language modes and is now being rejected in all C language modes. >From b43245ad55000f2567dcb9e0c5535cc37b5bc1e2 Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Thu, 7 Nov 2024 08:09:48 -0500 Subject: [PATCH] [C2y] Implement WG14 N3344 https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3344.pdf This paper disallows a single `void` parameter from having qualifiers or storage class specifiers. Clang has diagnosed most of these as an error for a long time, but `register void` was previously accepted in all C language modes and is now being rejected in all C language modes. --- clang/docs/ReleaseNotes.rst | 6 ++++++ clang/lib/Sema/SemaDecl.cpp | 18 +++++++++++++++--- clang/test/C/C2y/n3344.c | 28 ++++++++++++++++++++++++++++ clang/www/c_status.html | 2 +- 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 clang/test/C/C2y/n3344.c diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 061a1fed3f7d48..3e7d8e15110f9d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -280,6 +280,12 @@ C2y Feature Support this is now a C2y extension in C. ``-Wgnu-case-range`` still applies in C++ modes. +- Clang implemented support for `N3344 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3344.pdf>`_ + which disallows a ``void`` parameter from having a qualifier or storage class + specifier. Note that ``register void`` was previously accepted in all C + language modes but is now rejected (all of the other qualifiers and storage + class specifiers were previously rejected). + C23 Feature Support ^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index aba6b555ff28f3..c9cd81a48fbe51 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15002,6 +15002,12 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D, const DeclSpec &DS = D.getDeclSpec(); // Verify C99 6.7.5.3p2: The only SCS allowed is 'register'. + // C2y 6.7.7.4p4: A parameter declaration shall not specify a void type, + // except for the special case of a single unnamed parameter of type void + // with no storage class specifier, no type qualifier, and no following + // ellipsis terminator. + // Clang applies the C2y rules for 'register void' in all C language modes, + // same as GCC, because it's questionable what that could possibly mean. // C++03 [dcl.stc]p2 also permits 'auto'. StorageClass SC = SC_None; @@ -15010,10 +15016,16 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D, // In C++11, the 'register' storage class specifier is deprecated. // In C++17, it is not allowed, but we tolerate it as an extension. if (getLangOpts().CPlusPlus11) { + Diag(DS.getStorageClassSpecLoc(), getLangOpts().CPlusPlus17 + ? diag::ext_register_storage_class + : diag::warn_deprecated_register) + << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); + } else if (!getLangOpts().CPlusPlus && + DS.getTypeSpecType() == DeclSpec::TST_void) { Diag(DS.getStorageClassSpecLoc(), - getLangOpts().CPlusPlus17 ? diag::ext_register_storage_class - : diag::warn_deprecated_register) - << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); + diag::err_invalid_storage_class_in_func_decl) + << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); + D.getMutableDeclSpec().ClearStorageClassSpecs(); } } else if (getLangOpts().CPlusPlus && DS.getStorageClassSpec() == DeclSpec::SCS_auto) { diff --git a/clang/test/C/C2y/n3344.c b/clang/test/C/C2y/n3344.c new file mode 100644 index 00000000000000..bd3d440cb5d12a --- /dev/null +++ b/clang/test/C/C2y/n3344.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic %s +// RUN: %clang_cc1 -verify -Wall -pedantic %s + +/* WG14 N3344: Yes + * Slay Some Earthly Demons VI + * + * A 'void' parameter cannot have any qualifiers, storage class specifiers, or + * be followed by an ellipsis. + * + * Note: Clang treats 'register void' as being a DR and rejects it in all + * language modes; there's no evidence that this will break users and it's not + * clear what the programmer intended if they wrote such code anyway. This + * matches GCC's behavior. + */ + +void baz(volatile void); // expected-error {{'void' as parameter must not have type qualifiers}} +void bar(const void); // expected-error {{'void' as parameter must not have type qualifiers}} +void foo(register void); // expected-error {{invalid storage class specifier in function declarator}} +void quux(static void); // expected-error {{invalid storage class specifier in function declarator}} +void quobble(auto void); // expected-error {{invalid storage class specifier in function declarator}} +void quubble(extern void); // expected-error {{invalid storage class specifier in function declarator}} +// FIXME: it's odd that these aren't diagnosed as storage class specifiers. +#if __STDC_VERSION__ >= 202311L +void quibble(constexpr void); // expected-error {{function parameter cannot be constexpr}} +#endif +void quabble(_Thread_local void); // expected-error {{'_Thread_local' is only allowed on variable declarations}} +void bing(void, ...); // expected-error {{'void' must be the first and only parameter if specified}} + diff --git a/clang/www/c_status.html b/clang/www/c_status.html index 8b677095cee182..e66424290e6d50 100644 --- a/clang/www/c_status.html +++ b/clang/www/c_status.html @@ -201,7 +201,7 @@ <h2 id="c2y">C2y implementation status</h2> <tr> <td>Slay Some Earthly Demons VI</td> <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3344.pdf">N3344</a></td> - <td class="unknown" align="center">Unknown</td> + <td class="unreleased" align="center">Clang 20</td> </tr> <tr> <td>Slay Some Earthly Demons VII</td> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits