Message ID | ZIxOaoCXVo++78RO@arm.com |
---|---|
State | New |
Headers | show |
Series | [v3] c++: Accept elaborated-enum-base with pedwarn | expand |
On 6/16/23 07:58, Alex Coplan wrote: > Hi, > > This is a v3 patch addressing feedback for: > https://gcc.gnu.org/pipermail/gcc-patches/2023-June/621714.html > > The only change since the previous version is that the new option is > documented in invoke.texi (and the description in c.opt was shortened as > requested). > > ------ > > macOS SDK headers using the CF_ENUM macro can expand to invalid C++ code > of the form: > > typedef enum T : BaseType T; > > i.e. an elaborated-type-specifier with an additional enum-base. > Upstream LLVM can be made to accept the above construct with > -Wno-error=elaborated-enum-base. > > This patch adds the -Welaborated-enum-base warning to GCC and adjusts > the C++ parser to emit this warning instead of rejecting this code > outright. > > The macro expansion in the macOS headers occurs in the case that the > compiler declares support for enums with underlying type using > __has_feature, see > https://gcc.gnu.org/pipermail/gcc-patches/2023-May/618450.html > > GCC rejecting this construct outright means that GCC fails to bootstrap > on Darwin in the case that it (correctly) implements __has_feature and > declares support for C++ enums with underlying type. > > With this patch, GCC can bootstrap on Darwin in combination with the > (WIP) __has_feature patch posted at: > https://gcc.gnu.org/pipermail/gcc-patches/2023-May/617878.html > > Bootstrapped/regtested on aarch64-linux-gnu and x86_64-apple-darwin. > OK for trunk? OK, thanks. > Thanks, > Alex > > gcc/c-family/ChangeLog: > > * c.opt (Welaborated-enum-base): New. > > gcc/ChangeLog: > > * doc/invoke.texi: Document -Welaborated-enum-base. > > gcc/cp/ChangeLog: > > * parser.cc (cp_parser_enum_specifier): Don't reject > elaborated-type-specifier with enum-base, instead emit new > Welaborated-enum-base warning. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/enum40.C: Adjust expected diagnostics. > * g++.dg/cpp0x/forw_enum6.C: Likewise. > * g++.dg/cpp0x/elab-enum-base.C: New test.
On 16/06/2023 09:07, Jason Merrill wrote: > On 6/16/23 07:58, Alex Coplan wrote: > > Hi, > > > > This is a v3 patch addressing feedback for: > > https://gcc.gnu.org/pipermail/gcc-patches/2023-June/621714.html > > > > The only change since the previous version is that the new option is > > documented in invoke.texi (and the description in c.opt was shortened as > > requested). > > > > ------ > > > > macOS SDK headers using the CF_ENUM macro can expand to invalid C++ code > > of the form: > > > > typedef enum T : BaseType T; > > > > i.e. an elaborated-type-specifier with an additional enum-base. > > Upstream LLVM can be made to accept the above construct with > > -Wno-error=elaborated-enum-base. > > > > This patch adds the -Welaborated-enum-base warning to GCC and adjusts > > the C++ parser to emit this warning instead of rejecting this code > > outright. > > > > The macro expansion in the macOS headers occurs in the case that the > > compiler declares support for enums with underlying type using > > __has_feature, see > > https://gcc.gnu.org/pipermail/gcc-patches/2023-May/618450.html > > > > GCC rejecting this construct outright means that GCC fails to bootstrap > > on Darwin in the case that it (correctly) implements __has_feature and > > declares support for C++ enums with underlying type. > > > > With this patch, GCC can bootstrap on Darwin in combination with the > > (WIP) __has_feature patch posted at: > > https://gcc.gnu.org/pipermail/gcc-patches/2023-May/617878.html > > > > Bootstrapped/regtested on aarch64-linux-gnu and x86_64-apple-darwin. > > OK for trunk? > > OK, thanks. Thanks for the reviews, pushed as g:b106f11dc6adb8df15cc5c268896d314c76ca35f. > > > Thanks, > > Alex > > > > gcc/c-family/ChangeLog: > > > > * c.opt (Welaborated-enum-base): New. > > > > gcc/ChangeLog: > > > > * doc/invoke.texi: Document -Welaborated-enum-base. > > > > gcc/cp/ChangeLog: > > > > * parser.cc (cp_parser_enum_specifier): Don't reject > > elaborated-type-specifier with enum-base, instead emit new > > Welaborated-enum-base warning. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp0x/enum40.C: Adjust expected diagnostics. > > * g++.dg/cpp0x/forw_enum6.C: Likewise. > > * g++.dg/cpp0x/elab-enum-base.C: New test. >
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index cead1995561..0930a3c0422 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1488,6 +1488,10 @@ Wsubobject-linkage C++ ObjC++ Var(warn_subobject_linkage) Warning Init(1) Warn if a class type has a base or a field whose type uses the anonymous namespace or depends on a type with no linkage. +Welaborated-enum-base +C++ ObjC++ Var(warn_elaborated_enum_base) Warning Init(1) +Warn if an additional enum-base is used in an elaborated-type-specifier. + Wduplicate-decl-specifier C ObjC Var(warn_duplicate_decl_specifier) Warning LangEnabledBy(C ObjC,Wall) Warn when a declaration has duplicate const, volatile, restrict or _Atomic specifier. diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index d77fbd20e56..4dd290717de 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -21024,11 +21024,13 @@ cp_parser_enum_specifier (cp_parser* parser) /* Check for the `:' that denotes a specified underlying type in C++0x. Note that a ':' could also indicate a bitfield width, however. */ + location_t colon_loc = UNKNOWN_LOCATION; if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) { cp_decl_specifier_seq type_specifiers; /* Consume the `:'. */ + colon_loc = cp_lexer_peek_token (parser->lexer)->location; cp_lexer_consume_token (parser->lexer); auto tdf @@ -21077,10 +21079,13 @@ cp_parser_enum_specifier (cp_parser* parser) && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) { if (has_underlying_type) - cp_parser_commit_to_tentative_parse (parser); - cp_parser_error (parser, "expected %<;%> or %<{%>"); - if (has_underlying_type) - return error_mark_node; + pedwarn (colon_loc, + OPT_Welaborated_enum_base, + "declaration of enumeration with " + "fixed underlying type and no enumerator list is " + "only permitted as a standalone declaration"); + else + cp_parser_error (parser, "expected %<;%> or %<{%>"); } } diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 6d08229ce40..8ee5ba15709 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -254,7 +254,8 @@ in the following sections. -Wdelete-non-virtual-dtor -Wno-deprecated-array-compare -Wdeprecated-copy -Wdeprecated-copy-dtor -Wno-deprecated-enum-enum-conversion -Wno-deprecated-enum-float-conversion --Weffc++ -Wno-exceptions -Wextra-semi -Wno-inaccessible-base +-Weffc++ -Wno-elaborated-enum-base +-Wno-exceptions -Wextra-semi -Wno-inaccessible-base -Wno-inherited-variadic-ctor -Wno-init-list-lifetime -Winvalid-constexpr -Winvalid-imported-macros -Wno-invalid-offsetof -Wno-literal-suffix @@ -3846,6 +3847,15 @@ bool b = e <= 3.7; @option{-std=c++20}. In pre-C++20 dialects, this warning can be enabled by @option{-Wenum-conversion}. +@opindex Welaborated-enum-base +@opindex Wno-elaborated-enum-base +@item -Wno-elaborated-enum-base +For C++11 and above, warn if an (invalid) additional enum-base is used +in an elaborated-type-specifier. That is, if an enum with given +underlying type and no enumerator list is used in a declaration other +than just a standalone declaration of the enum. Enabled by default. This +warning is upgraded to an error with -pedantic-errors. + @opindex Winit-list-lifetime @opindex Wno-init-list-lifetime @item -Wno-init-list-lifetime @r{(C++ and Objective-C++ only)} @@ -6055,6 +6065,7 @@ errors by @option{-pedantic-errors}. For instance: -Wchanges-meaning @r{(C++)} -Wcomma-subscript @r{(C++23 or later)} -Wdeclaration-after-statement @r{(C90 or earlier)} +-Welaborated-enum-base @r{(C++11 or later)} -Wimplicit-int @r{(C99 or later)} -Wimplicit-function-declaration @r{(C99 or later)} -Wincompatible-pointer-types diff --git a/gcc/testsuite/g++.dg/cpp0x/elab-enum-base.C b/gcc/testsuite/g++.dg/cpp0x/elab-enum-base.C new file mode 100644 index 00000000000..57141f013bd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/elab-enum-base.C @@ -0,0 +1,7 @@ +// { dg-do compile { target c++11 } } +// { dg-options "" } +// Empty dg-options to override -pedantic-errors. + +typedef long CFIndex; +typedef enum CFComparisonResult : CFIndex CFComparisonResult; +// { dg-warning "declaration of enumeration with fixed underlying type" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/g++.dg/cpp0x/enum40.C b/gcc/testsuite/g++.dg/cpp0x/enum40.C index cfdf2a4a18a..d3ffeb62d70 100644 --- a/gcc/testsuite/g++.dg/cpp0x/enum40.C +++ b/gcc/testsuite/g++.dg/cpp0x/enum40.C @@ -4,23 +4,25 @@ void foo () { - enum : int a alignas; // { dg-error "expected" } + enum : int a alignas; // { dg-error "declaration of enum" } + // { dg-error {expected '\(' before ';'} "" { target *-*-* } .-1 } } void bar () { - enum : int a; // { dg-error "expected" } + enum : int a; // { dg-error "declaration of enum" } } void baz () { - enum class a : int b alignas; // { dg-error "expected" } + enum class a : int b alignas; // { dg-error "declaration of enum" } + // { dg-error {expected '\(' before ';'} "" { target *-*-* } .-1 } } void qux () { - enum class a : int b; // { dg-error "expected" } + enum class a : int b; // { dg-error "declaration of enum" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/forw_enum6.C b/gcc/testsuite/g++.dg/cpp0x/forw_enum6.C index 01bf563bcdd..8ad3f733292 100644 --- a/gcc/testsuite/g++.dg/cpp0x/forw_enum6.C +++ b/gcc/testsuite/g++.dg/cpp0x/forw_enum6.C @@ -23,7 +23,7 @@ enum class E7 : int; //ok enum class E3 e3; // { dg-error "scoped enum must not use" } enum struct E3 e4; // { dg-error "scoped enum must not use" } -enum E5 : int e5; // { dg-error "expected|invalid type" } +enum E5 : int e5; // { dg-error "declaration of enumeration with fixed underlying type|invalid type" } enum E6 : int { a, b, c }; // { dg-message "previous definition" } enum E6 : int { a, b, c }; // { dg-error "multiple definition" }