This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/41127
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 31 Aug 2009 17:08:22 -0400
- Subject: C++ PATCH for c++/41127
We were committing too soon to parsing "enum name :" as a C++0x enum
with explicit underlying type, when it can still be a type-specifier in
a bit-field declaration. Straightforward fix.
Tested x86_64-pc-linux-gnu, applied to trunk.
2009-08-31 Jason Merrill <jason@redhat.com>
PR c++/41127
* parser.c (cp_parser_enum_specifier): Make sure the : is followed by a
type-specifier-seq before we commit.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a3e9f0e..64869cd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -11967,11 +11967,19 @@ cp_parser_enum_specifier (cp_parser* parser)
else
identifier = make_anon_name ();
- /* Check for the `:' that denotes a specified underlying type in C++0x. */
+ /* Check for the `:' that denotes a specified underlying type in C++0x.
+ Note that a ':' could also indicate a bitfield width, however. */
if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
{
cp_decl_specifier_seq type_specifiers;
+ /* Consume the `:'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Parse the type-specifier-seq. */
+ cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+ &type_specifiers);
+
/* At this point this is surely not elaborated type specifier. */
if (!cp_parser_parse_definitely (parser))
return NULL_TREE;
@@ -11979,15 +11987,8 @@ cp_parser_enum_specifier (cp_parser* parser)
if (cxx_dialect == cxx98)
maybe_warn_cpp0x ("scoped enums");
- /* Consume the `:'. */
- cp_lexer_consume_token (parser->lexer);
-
has_underlying_type = true;
- /* Parse the type-specifier-seq. */
- cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
- &type_specifiers);
-
/* If that didn't work, stop. */
if (type_specifiers.type != error_mark_node)
{
diff --git a/gcc/testsuite/g++.dg/parse/enum5.C b/gcc/testsuite/g++.dg/parse/enum5.C
new file mode 100644
index 0000000..3ebb02f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/enum5.C
@@ -0,0 +1,17 @@
+// PR c++/41127
+
+#define CHAR_BIT 8
+enum EE {ee};
+typedef unsigned int T;
+
+struct D {
+ T : sizeof(unsigned int) * CHAR_BIT; // OK
+ EE : sizeof(EE) * CHAR_BIT; // OK
+ enum EE : sizeof(EE) * CHAR_BIT; // not OK
+ enum EE xxxx : sizeof(EE) * CHAR_BIT; // OK
+ T x : sizeof(unsigned int) * CHAR_BIT; // OK
+ enum FF {ff} : sizeof(int) * CHAR_BIT; // OK
+} element;
+
+enum EE xx;
+EE yy;
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum1.C b/gcc/testsuite/g++.dg/cpp0x/enum1.C
index af691f0..fb03692 100644
--- a/gcc/testsuite/g++.dg/cpp0x/enum1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/enum1.C
@@ -2,5 +2,5 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-enum : { }; // { dg-error "expected type-specifier" }
+enum : { }; // { dg-error "expected" }
enum : 3 { }; // { dg-error "expected" }