Gabriel Dos Reis <g...@integrable-solutions.net> a écrit:

> On Fri, Nov 16, 2012 at 8:51 AM, Jason Merrill <ja...@redhat.com> wrote:
>> Would it work to just do a cp_parser_commit_to_tentative_parse after we see
>> the '='?

I guess you mean in cp_parser_alias_declaration like in the updated
patch below?

> I like that solution better.

Ok, thanks.
 
I just had to adjust the call to cp_parser_alias_declaration when called
in  the context of a tentative parse, to handle the case where an error
occurs before we reach the '=' token; which means that the tentative
parse can still be cancelled.

Bootstrapped and tested on x86_64-unknown-linux-gnu against 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/parser.c                            | 23 +++++++++++++++++++++--
 gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C |  2 +-
 gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C |  7 +++++++
 3 files changed, 29 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7107134..2b76670 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -15260,7 +15260,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.  */
 
 static tree
 cp_parser_alias_declaration (cp_parser* parser)
@@ -15293,6 +15297,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.  */
 
   /*
@@ -15322,6 +15328,9 @@ 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)
+    return error_mark_node;
+
   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 
   if (cp_parser_error_occurred (parser))
@@ -19058,9 +19067,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/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" }
+};
-- 
                Dodji

Reply via email to