On Fri, Dec 7, 2012 at 7:33 AM, Dodji Seketeli <do...@redhat.com> wrote:
> Jason Merrill <ja...@redhat.com> writes:
>
>> Oops, thought I had sent this before.
>
> No problem.  Thank you for replying now×
>
>> On 11/17/2012 10:23 AM, Dodji Seketeli wrote:
>> > -     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);
>>
>> Maybe just check whether decl is error_mark_node?
>
> As we further discussed this on IRC, when cp_parser_alias_declaration
> returns error_mark_node, it is either because we encountered an error
> before the hypothetical '=', in which case we might want to try to
> parse a using declaration, or it is because we encountered an error
> after the the '=', in which case we committed to parsing an alias
> declaration and we must emit a hard error.
>
> And I believe what we want here is to tell the two possible cases
> apart.

Yes!

>
>>
>> > +  if (type == error_mark_node)
>> > +    return error_mark_node;
>>
>> I think for error-recovery we might want to
>> cp_parser_skip_to_end_of_block_or_statement as well.
>
> Right, done.
>
> 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                            | 31 
> +++++++++++++++++++++++++++---
>  gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C |  2 +-
>  gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C |  7 +++++++
>  3 files changed, 36 insertions(+), 4 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 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.


>
>  static tree
>  cp_parser_alias_declaration (cp_parser* parser)
> @@ -15295,6 +15299,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 +15330,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 +19078,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" }
> +};
> --
> 1.7.11.7
>
>
> --
>                 Dodji

Sound good to me (except for the comment).
thanks!

-- Gaby

Reply via email to