-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
elaborated-enum-base incompatible with NS_ENUM
#48757
Comments
The macro in question generates ill-formed code in C++; note that GCC and ICC also reject. As a result, Clang generates an error by default. (The code generated by the macro is valid in Objective-C and Objective-C++, though.) Because Clang historically incorrectly accepted this, and in particular because Apple's NS_ENUM macro currently relies on that compiler bug, we allow the error for this non-conforming code to be disabled with Hopefully Apple will fix their macro at some point, if they've not done so already. For example, this can be done with something like: #ifdef __cplusplus
#define NS_ENUM(name, underlying) \
void NS_ENUM_##name##_typedef(); \
enum name : underlying
#else
// old definition
#endif (where the first line of the macro expansion exists only to effectively swallow the preceding |
Should this warning only be active for |
The error is not produced in The 'enum name : underlying' syntax is not valid at all in C. As a Clang extension, we permit the C++ language feature in C as well, so the error is produced in Perhaps it would be better if, under Aaron, as our champion of C conformance, what do you think? Silently accepting this C++ feature in C by default seems at least questionable to me. |
I agree that silently accepting the feature in C by default is not the right behavior. WG14 is currently considering enumerations with underlying types for C (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2575.pdf) and is trying to get as close to the C++ semantics as possible (but are struggling a bit due to type system differences between C and C++), so my instinct is that we would want Clang to be closer to the C++ feature than the ObjC feature. |
Thanks, Aaron. It looks like N2575 as currently written does introduce the grammar production
which is the subject of this bug and would allow the testcases here. C++ has no such production because it makes things like Instead of adding such a general grammar production that would introduce ambiguities, C++ instead introduced a new form of top-level declaration
... which is always a standalone declaration and is the only way to introduce an enum name without also specifying a braced list of enumerators. If C intends to follow C++, the wording will presumably need to be changed. (And if not, it looks like a disambiguation rule is missing.)
OK, then keeping the error for the |
I agree. The wording in the current paper is known to be problematic and the author has been very welcoming of feedback on improvements to get better alignment. I'll pass along this bug report as a data point, but in the meantime, I would recommend we see what comes out of WG14 in this space.
Based on everything I know, I think this is a good approach for now. |
To work around llvm/llvm-project#48757.
NS_ENUM
@llvm/issue-subscribers-c Author: None (llvmbot)
| | |
| --- | --- |
| Bugzilla Link | [49413](https://llvm.org/bz49413) |
| Version | 11.0 |
| OS | MacOS X |
| Reporter | LLVM Bugzilla Contributor |
| CC | @AaronBallman,@DougGregor,@zygoloid |
Extended DescriptionRelated to c90e198 The new One such example is Apple's NS_ENUM, which effectively translates: typedef NS_ENUM( X, unsigned int) {
...
} into: typedef enum X : unsigned int X;
enum X : unsigned int { Which triggers:
The idea behind macros such as Unfortunately, the only way to do this now would be to remove the nonfixed type from the typedef, but this causes another problem:
This can only be addressed by moving the Consequently, |
Extended Description
Related to c90e198
The new
-Welaborated-enum-base
appears to be incompatible with macros to define nonfixed type enums.One such example is Apple's NS_ENUM, which effectively translates:
into:
Which triggers:
The idea behind macros such as
NS_ENUM
is that they type the enum if supported by the compiler, as well as hide theenum
type keyword.Unfortunately, the only way to do this now would be to remove the nonfixed type from the typedef, but this causes another problem:
This can only be addressed by moving the
typedef
below the enum declaration, but unfortunately it appears that this is impossible to achieve with a macro.Consequently,
clang
can no longer compileNS_ENUM
-style macros, and there is no path for resolving the issue other than by disablingelaborated-enum-base
.The text was updated successfully, but these errors were encountered: