diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2022-06-06 07:17:35 -0400 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2022-06-06 07:17:35 -0400 |
commit | 881125ad9178120acef186f579e36ced0888dfdb (patch) | |
tree | 1a9b07e2437733a30739705a291bdaf6a6c41efa /clang/lib/Parse/ParseDecl.cpp | |
parent | 4ea1b43527c9a845942dbbc27e022d74d72728e6 (diff) | |
download | llvm-881125ad9178120acef186f579e36ced0888dfdb.zip llvm-881125ad9178120acef186f579e36ced0888dfdb.tar.gz llvm-881125ad9178120acef186f579e36ced0888dfdb.tar.bz2 |
Allow use of an elaborated type specifier in a _Generic association in C++
Currently, Clang accepts this code in C mode (where the tag is required
to be used) but rejects it in C++ mode thinking that the association is
defining a new type.
void foo(void) {
struct S { int a; };
_Generic(something, struct S : 1);
}
Clang thinks this in C++ because it sees struct S : when parsing the
class specifier and decides that must be a type definition (because the
colon signifies the presence of a base class type). This patch adds a
new declarator context to represent a _Generic association so that we
can distinguish these situations properly.
Fixes #55562
Differential Revision: https://reviews.llvm.org/D126969
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 18f4f12..0cdf915 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2870,6 +2870,8 @@ Parser::getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context) { if (Context == DeclaratorContext::AliasDecl || Context == DeclaratorContext::AliasTemplate) return DeclSpecContext::DSC_alias_declaration; + if (Context == DeclaratorContext::Association) + return DeclSpecContext::DSC_association; return DeclSpecContext::DSC_normal; } @@ -4573,7 +4575,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, // Determine whether this declaration is permitted to have an enum-base. AllowDefiningTypeSpec AllowEnumSpecifier = - isDefiningTypeSpecifierContext(DSC); + isDefiningTypeSpecifierContext(DSC, getLangOpts().CPlusPlus); bool CanBeOpaqueEnumDeclaration = DS.isEmpty() && isOpaqueEnumDeclarationContext(DSC); bool CanHaveEnumBase = (getLangOpts().CPlusPlus11 || getLangOpts().ObjC || |