Gabriel Dos Reis <g...@integrable-solutions.net> writes: > On Fri, Dec 7, 2012 at 7:33 AM, Dodji Seketeli <do...@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 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 <do...@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 <ja...@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 <do...@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 <mjam...@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" } +}; -- Dodji