This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PING] [PATCH] PR c++/54401 - Confusing diagnostics about type-alias at class scope
- From: Dodji Seketeli <dodji at redhat dot com>
- To: Gabriel Dos Reis <gdr at integrable-solutions dot net>
- Cc: Jason Merrill <jason at redhat dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 07 Dec 2012 17:06:30 +0100
- Subject: Re: [PING] [PATCH] PR c++/54401 - Confusing diagnostics about type-alias at class scope
- References: <87626yupft.fsf@redhat.com> <874nkpvfk3.fsf@seketeli.org> <50A652F6.9000804@redhat.com> <CAAiZkiBss5FCc2-aYi+2WVJt1qzoBt0mfNA0B7CVZA5GxXvFeA@mail.gmail.com> <87ehjstfrx.fsf@seketeli.org> <50BE29C5.7060507@redhat.com> <87zk1qasvv.fsf@redhat.com> <CAAiZkiAT-YCd3ML=VEx49q=XZdnBG=7LEJXpbY53RwJaLy=33g@mail.gmail.com>
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
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" }
+};
--
Dodji