Enforce the C++11 anonymous enum bitfields check even for

Objective-C++11 and under MS extensions.

This matches the MSVC behavior, and means that Objective-C behaves as a
set of extensions to the base language, rather than replacing the base
language rule with a different one.
This commit is contained in:
Richard Smith 2020-05-10 13:58:42 -07:00
parent 2d3f5a62de
commit 8fc12b8698
4 changed files with 22 additions and 3 deletions

View File

@ -4543,8 +4543,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
// Outside C++11, do not interpret the tokens as an enum-base if they do
// not make sense as one. In C++11, it's an error if this happens.
if (getLangOpts().CPlusPlus11 && !getLangOpts().ObjC &&
!getLangOpts().MicrosoftExt)
if (getLangOpts().CPlusPlus11)
Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
} else if (CanHaveEnumBase || !ColonIsSacred) {
SourceLocation ColonLoc = ConsumeToken();

View File

@ -455,4 +455,17 @@ namespace enum_class {
auto f4() -> enum class E4 { return {}; }
auto f5() -> enum E5 : int { return {}; } // FIXME: MSVC rejects this and crashes if the body is {}.
auto f6() -> enum E6 { return {}; } // expected-warning {{Microsoft extension}}
// MSVC does not perform disambiguation for a colon that could introduce an
// enum-base or a bit-field.
enum E {};
struct S {
enum E : int(1); // expected-error {{anonymous bit-field}}
enum E : int : 1; // OK, bit-field
enum F : int a = {}; // OK, default member initializer
// MSVC produces a "C4353 constant 0 as function expression" for this,
// considering the final {} to be part of the bit-width. We follow P0683R1
// and treat it as a default member initializer.
enum E : int : int{}{}; // expected-error {{anonymous bit-field cannot have a default member initializer}} expected-warning {{C++20 extension}}
};
}

View File

@ -1,10 +1,14 @@
// RUN: %clang_cc1 -verify -std=c++98 %s
// RUN: %clang_cc1 -verify=cxx11 -std=c++11 %s
#if __cplusplus < 201103L
// expected-no-diagnostics
#endif
// Objective-C allows C++11 enumerations in C++98 mode. We disambiguate in
// order to make this a backwards-compatible extension.
struct A {
enum E : int{a}; // OK, enum definition
enum E : int(a); // OK, bit-field declaration
enum E : int(a); // OK, bit-field declaration cxx11-error{{anonymous bit-field}}
};
_Static_assert(A::a == 0, "");

View File

@ -154,6 +154,9 @@ struct X0 {
#endif
enum E1 : seventeen;
#if __cplusplus >= 201103L
// expected-error@-2 {{bit-field}}
#endif
};
#if __cplusplus <= 199711L