This is an archive of the discontinued LLVM Phabricator instance.

Allow use of an elaborated type specifier in a _Generic association in C++
ClosedPublic

Authored by aaron.ballman on Jun 3 2022, 8:53 AM.

Details

Summary

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

Diff Detail

Event Timeline

aaron.ballman created this revision.Jun 3 2022, 8:53 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 3 2022, 8:53 AM
aaron.ballman requested review of this revision.Jun 3 2022, 8:53 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 3 2022, 8:53 AM

This mostly/all seems reasonable to me, and the diagnostics, while not perfect, are IMO a vast improvement.

clang/include/clang/Sema/DeclSpec.h
2068

Is this right? According to the comment, this is 'true'if the identifier is optional or required, but the mayOmitIdentifier, where you are returning 'true' says optional or not allowed? Does this make identifier 'not allowed' here?

aaron.ballman marked an inline comment as done.Jun 3 2022, 10:03 AM
aaron.ballman added inline comments.
clang/include/clang/Sema/DeclSpec.h
2068

I believe this is correct -- associations used to be handled the same as type names, and we still want to handle them effectively as type names. The only distinction between an association and a type name is whether it can be a defining type specifier or not (type name can be, association cannot be).

This is the function that tests whether you can put an identifier after the type; e.g., int a and I think it's logically consistent. May the identifier be omitted? Certainly, it must be. May it have an identifier? Definitely not.

erichkeane accepted this revision.Jun 3 2022, 10:08 AM
erichkeane added inline comments.
clang/include/clang/Sema/DeclSpec.h
2068

Ok, that sounds right to me as well then. Its a little annoying/confusing I guess that these two functions combine for a bizarre tri-state: "Required/Optional/Not-allowed", and the name of mayOmitIdentifier isn't really a good one, since may I omit implies the option here...

Either way, not your ball of wax, but thanks for confirming.

This revision is now accepted and ready to land.Jun 3 2022, 10:08 AM
aaron.ballman marked an inline comment as done.Jun 3 2022, 11:17 AM

Thanks for the reviews @erichkeane! I'll probably land this on Monday just in case @jyknight has comments.

This revision was landed with ongoing or failed builds.Jun 6 2022, 4:18 AM
This revision was automatically updated to reflect the committed changes.