Hi,

On 10/09/2013 03:56 PM, Jason Merrill wrote:
On 10/08/2013 07:03 PM, Paolo Carlini wrote:
.. a curiosity: the cp_parser_commit_to_tentative_parse at the end of
cp_parser_pseudo_destructor_name, which didn't exist in 4.6.x and we can
consider the root of this issue, is also my fault:

     http://gcc.gnu.org/ml/gcc-patches/2011-05/msg02246.html

 From a different angle, I'm happy of the outcome of this detective
work, because it means that the parser_commit isn't there for
correctness: not performing it in some cases shouldn't be a big issue.

Yeah. I don't understand why cp_parser_commit_to_tentative_parse commits all levels, rather than just the current one as the comment seems to suggest. Mark, do you remember anything about that decision?
Well, the below appears to work for the testcase at issue and even appears to pass the testsuite. Not sure how far we want to go at this time, what should we double chech...

Paolo.

//////////////////////
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 203320)
+++ cp/parser.c (working copy)
@@ -2347,6 +2347,8 @@ static void cp_parser_parse_tentatively
   (cp_parser *);
 static void cp_parser_commit_to_tentative_parse
   (cp_parser *);
+static void cp_parser_commit_to_topmost_tentative_parse
+  (cp_parser *);
 static void cp_parser_abort_tentative_parse
   (cp_parser *);
 static bool cp_parser_parse_definitely
@@ -6693,7 +6695,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parse
 
   /* Once we see the ~, this has to be a pseudo-destructor.  */
   if (!processing_template_decl && !cp_parser_error_occurred (parser))
-    cp_parser_commit_to_tentative_parse (parser);
+    cp_parser_commit_to_topmost_tentative_parse (parser);
 
   /* Look for the type-name again.  We are not responsible for
      checking that it matches the first type-name.  */
@@ -24346,6 +24348,26 @@ cp_parser_commit_to_tentative_parse (cp_parser* pa
     }
 }
 
+/* Commit to the topmost currently active tentative parse.  */
+
+static void
+cp_parser_commit_to_topmost_tentative_parse (cp_parser* parser)
+{
+  cp_parser_context *context = parser->context;
+  cp_lexer *lexer = parser->lexer;
+
+  if (context)
+    {
+      if (context->status == CP_PARSER_STATUS_KIND_COMMITTED)
+       return;
+      context->status = CP_PARSER_STATUS_KIND_COMMITTED;
+
+      while (!cp_lexer_saving_tokens (lexer))
+       lexer = lexer->next;
+      cp_lexer_commit_tokens (lexer);
+    }
+}
+
 /* Abort the currently active tentative parse.  All consumed tokens
    will be rolled back, and no diagnostics will be issued.  */
 
Index: testsuite/g++.dg/cpp0x/decltype57.C
===================================================================
--- testsuite/g++.dg/cpp0x/decltype57.C (revision 0)
+++ testsuite/g++.dg/cpp0x/decltype57.C (working copy)
@@ -0,0 +1,8 @@
+// PR c++/58633
+// { dg-do compile { target c++11 } }
+
+void foo(int i)
+{
+  typedef int I;
+  decltype(i.I::~I())* p;
+}

Reply via email to