Patchwork [PING] PR c++/54401 - Confusing diagnostics about type-alias at class scope

login
register
mail settings
Submitter Dodji Seketeli
Date Dec. 7, 2012, 4:06 p.m.
Message ID <87r4n1c0e1.fsf@redhat.com>
Download mbox | patch
Permalink /patch/204573/
State New
Headers show

Comments

Dodji Seketeli - Dec. 7, 2012, 4:06 p.m.
Gabriel Dos Reis <gdr@integrable-solutions.net> writes:

> On Fri, Dec 7, 2012 at 7:33 AM, Dodji Seketeli <dodji@redhat.com> wrote:

>> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
>> index a010f1f..c39ef30 100644
>> --- a/gcc/cp/parser.c
>> +++ b/gcc/cp/parser.c
>> @@ -15262,7 +15262,11 @@ cp_parser_using_declaration (cp_parser* parser,
>>  /* Parse an alias-declaration.
>>
>>     alias-declaration:
>> -     using identifier attribute-specifier-seq [opt] = type-id  */
>> +     using identifier attribute-specifier-seq [opt] = type-id
>> +
>> +   Note that if this function is used in the context of a tentative
>> +   parse, it commits the currently active tentative parse after it
>> +   sees the '=' token.  */
>
> This comment is repeated below; I don't think it is necessary
> or should be part of the specification.  In general we don't (and shouldn't)
> say this unless a parsing function deviates from the general
> parsing strategy -- this one doesn't.

Fair enough.  I have removed this comment then.  Thanks.

> Sound good to me (except for the comment).

Thanks!

Here is what I am committing to trunk.

gcc/cp/

	* parser.c (cp_parser_alias_declaration): Commit to tentative
	parse when see the '=' token.  Get out if the type-id is invalid.
	Update function comment.
	(cp_parser_member_declaration): Don't try to parse a using
	declaration if we know that we expected an alias declaration; that
	is, if we see the '=' token after the identifier.

gcc/testsuite/

	* g++.dg/cpp0x/alias-decl-28.C: New test.
	* g++.dg/cpp0x/alias-decl-16.C: Update.
---
 gcc/cp/ChangeLog                           | 10 ++++++++++
 gcc/cp/parser.c                            | 25 +++++++++++++++++++++++--
 gcc/testsuite/ChangeLog                    |  6 ++++++
 gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C |  2 +-
 gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C |  7 +++++++
 5 files changed, 47 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C
Gabriel Dos Reis - Dec. 7, 2012, 8:04 p.m.
On Fri, Dec 7, 2012 at 10:06 AM, Dodji Seketeli <dodji@redhat.com> wrote:

> Here is what I am committing to trunk.

Thank you!

-- Gaby

Patch

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7bec9ca..81c2048 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@ 
+2012-12-07  Dodji Seketeli  <dodji@redhat.com>
+
+	PR c++/54401
+	* parser.c (cp_parser_alias_declaration): Commit to tentative
+	parse when see the '=' token.  Get out if the type-id is invalid.
+	Update function comment.
+	(cp_parser_member_declaration): Don't try to parse a using
+	declaration if we know that we expected an alias declaration; that
+	is, if we see the '=' token after the identifier.
+
 2012-12-06  Jason Merrill  <jason@redhat.com>
 
 	PR c++/54325
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 3566d74..3dc2ec6 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -15295,6 +15295,8 @@  cp_parser_alias_declaration (cp_parser* parser)
   if (cp_parser_error_occurred (parser))
     return error_mark_node;
 
+  cp_parser_commit_to_tentative_parse (parser);
+
   /* Now we are going to parse the type-id of the declaration.  */
 
   /*
@@ -15324,10 +15326,19 @@  cp_parser_alias_declaration (cp_parser* parser)
   if (parser->num_template_parameter_lists)
     parser->type_definition_forbidden_message = saved_message;
 
+  if (type == error_mark_node)
+    {
+      cp_parser_skip_to_end_of_block_or_statement (parser);
+      return error_mark_node;
+    }
+
   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 
   if (cp_parser_error_occurred (parser))
-    return error_mark_node;
+    {
+      cp_parser_skip_to_end_of_block_or_statement (parser);
+      return error_mark_node;
+    }
 
   /* A typedef-name can also be introduced by an alias-declaration. The
      identifier following the using keyword becomes a typedef-name. It has
@@ -19063,9 +19074,19 @@  cp_parser_member_declaration (cp_parser* parser)
       else
 	{
 	  tree decl;
+	  bool alias_decl_expected;
 	  cp_parser_parse_tentatively (parser);
 	  decl = cp_parser_alias_declaration (parser);
-	  if (cp_parser_parse_definitely (parser))
+	  /* Note that if we actually see the '=' token after the
+	     identifier, cp_parser_alias_declaration commits the
+	     tentative parse.  In that case, we really expects an
+	     alias-declaration.  Otherwise, we expect a using
+	     declaration.  */
+	  alias_decl_expected =
+	    !cp_parser_uncommitted_to_tentative_parse_p (parser);
+	  cp_parser_parse_definitely (parser);
+
+	  if (alias_decl_expected)
 	    finish_member_declaration (decl);
 	  else
 	    cp_parser_using_declaration (parser,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d50d73b..1fd69fa 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@ 
+2012-12-07  Dodji Seketeli  <dodji@redhat.com>
+
+	PR c++/54401
+	* g++.dg/cpp0x/alias-decl-28.C: New test.
+	* g++.dg/cpp0x/alias-decl-16.C: Update.
+
 2012-12-07  Martin Jambor  <mjambor@suse.cz>
 
 	PR tree-optimization/55590
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C
index d66660a..ce6ad0a 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C
@@ -23,6 +23,6 @@  template<class T>
 using A3 =
     enum B3 {b = 0;}; //{ dg-error "types may not be defined in alias template" }
 
-A3<int> a3;
+A3<int> a3; // { dg-error "'A3' does not name a type" }
 
 int main() { }
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C
new file mode 100644
index 0000000..086b5e5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C
@@ -0,0 +1,7 @@ 
+// Origin: PR c++/54401
+// { dg-do compile { target c++11 } }
+
+template<typename>
+struct X {
+    using type = T; // { dg-error "expected type-specifier|does not name a type" }
+};