diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2024-11-07 10:34:00 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-07 10:34:00 -0500 |
commit | 24e2e259a06d9aa67dc278ac24dcb98da9dd63f6 (patch) | |
tree | 4c192ad8d883ae91ade4973e7f6f0f0ac281775c /clang/lib/Sema/SemaDecl.cpp | |
parent | 85eec89600085a054650585d3a3287a6e0a93a50 (diff) | |
download | llvm-24e2e259a06d9aa67dc278ac24dcb98da9dd63f6.zip llvm-24e2e259a06d9aa67dc278ac24dcb98da9dd63f6.tar.gz llvm-24e2e259a06d9aa67dc278ac24dcb98da9dd63f6.tar.bz2 |
[C2y] Implement WG14 N3344 (#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.
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index aba6b55..c9cd81a 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) { |