public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-1890] c++: Accept elaborated-enum-base with pedwarn
@ 2023-06-16 14:22 Alex Coplan
  0 siblings, 0 replies; only message in thread
From: Alex Coplan @ 2023-06-16 14:22 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b106f11dc6adb8df15cc5c268896d314c76ca35f

commit r14-1890-gb106f11dc6adb8df15cc5c268896d314c76ca35f
Author: Alex Coplan <alex.coplan@arm.com>
Date:   Fri Jun 16 15:18:40 2023 +0100

    c++: Accept elaborated-enum-base with pedwarn
    
    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
    
    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:
---
 gcc/c-family/c.opt                          |  4 ++++
 gcc/cp/parser.cc                            | 13 +++++++++----
 gcc/doc/invoke.texi                         | 13 ++++++++++++-
 gcc/testsuite/g++.dg/cpp0x/elab-enum-base.C |  7 +++++++
 gcc/testsuite/g++.dg/cpp0x/enum40.C         | 10 ++++++----
 gcc/testsuite/g++.dg/cpp0x/forw_enum6.C     |  2 +-
 6 files changed, 39 insertions(+), 10 deletions(-)

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 f5f9f5a4510..dd3665c8ccf 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -21028,11 +21028,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
@@ -21081,10 +21083,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 19d8c1c9aa5..fafdee30f66 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
@@ -3845,6 +3846,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)}
@@ -6054,6 +6064,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" }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-16 14:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-16 14:22 [gcc r14-1890] c++: Accept elaborated-enum-base with pedwarn Alex Coplan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).