Skip to content

Commit

Permalink
Enforce the C++11 anonymous enum bitfields check even for
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
zygoloid committed May 10, 2020
1 parent 2d3f5a6 commit 8fc12b8
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 3 deletions.
3 changes: 1 addition & 2 deletions clang/lib/Parse/ParseDecl.cpp
Expand Up @@ -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();
Expand Down
13 changes: 13 additions & 0 deletions clang/test/Parser/MicrosoftExtensions.cpp
Expand Up @@ -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}}
};
}
6 changes: 5 additions & 1 deletion clang/test/Parser/objcxx-enum.mm
@@ -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, "");
3 changes: 3 additions & 0 deletions clang/test/SemaCXX/MicrosoftExtensions.cpp
Expand Up @@ -154,6 +154,9 @@ struct X0 {
#endif

enum E1 : seventeen;
#if __cplusplus >= 201103L
// expected-error@-2 {{bit-field}}
#endif
};

#if __cplusplus <= 199711L
Expand Down

0 comments on commit 8fc12b8

Please sign in to comment.