diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 8a0d63f486c3a6..d5d499360a3951 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -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(); diff --git a/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp index 10eb13a56b007c..ddbe5aaef7790a 100644 --- a/clang/test/Parser/MicrosoftExtensions.cpp +++ b/clang/test/Parser/MicrosoftExtensions.cpp @@ -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}} + }; } diff --git a/clang/test/Parser/objcxx-enum.mm b/clang/test/Parser/objcxx-enum.mm index 2d68aa047a8aca..a86c420f9fbee9 100644 --- a/clang/test/Parser/objcxx-enum.mm +++ b/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, ""); diff --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp b/clang/test/SemaCXX/MicrosoftExtensions.cpp index c9703828366cfd..b1f8cd96d50526 100644 --- a/clang/test/SemaCXX/MicrosoftExtensions.cpp +++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp @@ -154,6 +154,9 @@ struct X0 { #endif enum E1 : seventeen; +#if __cplusplus >= 201103L + // expected-error@-2 {{bit-field}} +#endif }; #if __cplusplus <= 199711L