diff mbox

C++ PATCH for c++/54359 ('this' in trailing-return-type with out-of-class method defn)

Message ID 514A7C80.7010905@redhat.com
State New
Headers show

Commit Message

Jason Merrill March 21, 2013, 3:20 a.m. UTC
On 03/17/2013 11:45 PM, Jason Merrill wrote:
> This patch caused c++/56639: when within a function we were trying to
> parse something that could be either a declaration or an expression, we
> went to set current_class_ptr and failed the assertion that it wasn't
> already set.  We could save and restore the value

...and now this PR comes along that shows that we really do need to save 
and restore the value.

Tested x86_64-pc-linux-gnu, applying to trunk, and branches later.
diff mbox

Patch

commit e60c343e7913ad2ff194c95391d6dd8fc479ce88
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 20 22:51:38 2013 -0400

    	PR c++/56646
    	* parser.c (cp_parser_late_return_type_opt): Save and restore
    	current_class_ptr/ref.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 23fe3f3..e04d3ce 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -17056,17 +17056,21 @@  cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals)
   /* Consume the ->.  */
   cp_lexer_consume_token (parser->lexer);
 
+  tree save_ccp = current_class_ptr;
+  tree save_ccr = current_class_ref;
   if (quals >= 0)
     {
       /* DR 1207: 'this' is in scope in the trailing return type.  */
-      gcc_assert (current_class_ptr == NULL_TREE);
       inject_this_parameter (current_class_type, quals);
     }
 
   type = cp_parser_trailing_type_id (parser);
 
   if (quals >= 0)
-    current_class_ptr = current_class_ref = NULL_TREE;
+    {
+      current_class_ptr = save_ccp;
+      current_class_ref = save_ccr;
+    }
 
   return type;
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/trailing9.C b/gcc/testsuite/g++.dg/cpp0x/trailing9.C
new file mode 100644
index 0000000..d7895b3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/trailing9.C
@@ -0,0 +1,12 @@ 
+// PR c++/56646
+// { dg-require-effective-target c++11 }
+
+struct A {
+  void f();
+};
+
+void A::f() {
+  struct B {
+    auto g() -> void { }
+  };
+}