diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2024-02-15 07:58:01 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-15 07:58:01 -0500 |
commit | b9cf7f1066cc7ec11c6074d10b0f2ec9a3ae72d9 (patch) | |
tree | 75979a8d187ddba0a7f1537c9d6ec4889b57047e /clang/lib/Parse/ParseDecl.cpp | |
parent | c448bd8b043f57ac51145664d2edde6dae98e5ea (diff) | |
download | llvm-b9cf7f1066cc7ec11c6074d10b0f2ec9a3ae72d9.zip llvm-b9cf7f1066cc7ec11c6074d10b0f2ec9a3ae72d9.tar.gz llvm-b9cf7f1066cc7ec11c6074d10b0f2ec9a3ae72d9.tar.bz2 |
[C23] Fix handling of alignas (#81637)
In C++, alignas is an attribute specifier, while in C23, it's an alias
of _Alignas, which is a type specifier/qualifier. This means that they
parse differently in some circumstances.
Fixes https://github.com/llvm/llvm-project/issues/81472
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 94696d8..9640d7e 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3518,8 +3518,24 @@ void Parser::ParseDeclarationSpecifiers( DS.Finish(Actions, Policy); return; - case tok::l_square: + // alignment-specifier + case tok::kw__Alignas: + if (!getLangOpts().C11) + Diag(Tok, diag::ext_c11_feature) << Tok.getName(); + [[fallthrough]]; case tok::kw_alignas: + // _Alignas and alignas (C23, not C++) should parse the same way. The C++ + // parsing for alignas happens through the usual attribute parsing. This + // ensures that an alignas specifier can appear in a type position in C + // despite that not being valid in C++. + if (getLangOpts().C23 || Tok.getKind() == tok::kw__Alignas) { + if (Tok.getKind() == tok::kw_alignas) + Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName(); + ParseAlignmentSpecifier(DS.getAttributes()); + continue; + } + [[fallthrough]]; + case tok::l_square: if (!isAllowedCXX11AttributeSpecifier()) goto DoneWithDeclSpec; @@ -4234,13 +4250,6 @@ void Parser::ParseDeclarationSpecifiers( isInvalid = DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID); break; - // alignment-specifier - case tok::kw__Alignas: - if (!getLangOpts().C11) - Diag(Tok, diag::ext_c11_feature) << Tok.getName(); - ParseAlignmentSpecifier(DS.getAttributes()); - continue; - // friend case tok::kw_friend: if (DSContext == DeclSpecContext::DSC_class) @@ -5857,6 +5866,11 @@ bool Parser::isDeclarationSpecifier( case tok::kw__Atomic: return true; + case tok::kw_alignas: + // alignas is a type-specifier-qualifier in C23, which is a kind of + // declaration-specifier. Outside of C23 mode (including in C++), it is not. + return getLangOpts().C23; + // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'. case tok::less: return getLangOpts().ObjC; |