This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] Change order of tentative parsing in cp_parser_postfix_dot_deref_expression (PR c++/35138)
On Tue, Feb 12, 2008 at 02:41:30PM -0500, Jakub Jelinek wrote:
> If you mean something like attached patch, then that works too.
> To me it looks uglier though, because it repeats part of
> cp_parser_type_name/cp_parser_class_name to skip over tokens
> cp_parser_type_name would consume.
Or even following patch works too. If cp_parser_type_name ->
cp_parser_class_name decides to call cp_parser_template_id,
then cp_parser_id_expression would call it too, so that's not a case
it needs to fear that an error would be immediately reported during
tentative parsing. When cp_parser_type_name/cp_parser_class_name
don't call cp_parser_template_id, they consume just one CPP_NAME,
so we can check that even without going into yet another tentative
parse.
Regtested on x86_64-linux.
2008-02-12 Jakub Jelinek <jakub@redhat.com>
PR c++/35138
* parser.c (cp_parser_pseudo_destructor_name): If next token
is CPP_NAME, not followed by template argument list nor
::~, return before calling cp_parser_type_name.
* g++.dg/template/member8.C: New test.
--- gcc/cp/parser.c.jj 2008-02-12 14:49:55.000000000 +0100
+++ gcc/cp/parser.c 2008-02-12 20:47:09.000000000 +0100
@@ -5164,6 +5164,27 @@ cp_parser_pseudo_destructor_name (cp_par
additional qualification. */
else if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMPL))
{
+ /* If postfix-expression before . or -> token was dependent,
+ this might be actually a normal class access rather than
+ pseudo destructor. As cp_parser_type_name can report
+ errors, first make sure the identifier is followed
+ by `::~'. */
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ if (token->type != CPP_NAME && token->type != CPP_TEMPLATE_ID)
+ {
+ cp_parser_error (parser, "expected class-name");
+ return;
+ }
+
+ if (token->type == CPP_NAME
+ && !cp_parser_nth_token_starts_template_argument_list_p (parser, 2)
+ && (cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE
+ || cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_COMPL))
+ {
+ cp_parser_error (parser, "not a pseudo destructor");
+ return;
+ }
+
/* Look for the type-name. */
*scope = TREE_TYPE (cp_parser_type_name (parser));
--- gcc/testsuite/g++.dg/template/member8.C.jj 2008-02-12 18:32:14.000000000 +0100
+++ gcc/testsuite/g++.dg/template/member8.C 2008-02-12 18:19:23.000000000 +0100
@@ -0,0 +1,25 @@
+// PR c++/35138
+// { dg-do compile }
+
+namespace N1 { struct A { }; }
+namespace N2 { struct A { }; }
+using namespace N1;
+using namespace N2;
+
+template <typename T> int
+foo (T const &t)
+{
+ return t.A;
+}
+
+struct B
+{
+ int A;
+};
+
+int
+main ()
+{
+ B b;
+ foo (b);
+}
Jakub