re PR c++/56646 (ICE: in cp_parser_late_return_type_opt, at cp/parser.c:16970)
authorJason Merrill <jason@redhat.com>
Thu, 21 Mar 2013 03:25:42 +0000 (23:25 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 21 Mar 2013 03:25:42 +0000 (23:25 -0400)
PR c++/56646
* parser.c (cp_parser_late_return_type_opt): Save and restore
current_class_ptr/ref.

From-SVN: r196853

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/g++.dg/cpp0x/trailing9.C [new file with mode: 0644]

index 64a085c7fb5ea5b7cf577603cbb3abd5f34f5d87..704583802e5867ca5d24a4c2b13919b06fcb7a94 100644 (file)
@@ -1,5 +1,9 @@
 2013-03-20  Jason Merrill  <jason@redhat.com>
 
+       PR c++/56646
+       * parser.c (cp_parser_late_return_type_opt): Save and restore
+       current_class_ptr/ref.
+
        PR c++/54532
        * expr.c (cplus_expand_constant): Do nothing if the class is
        incomplete.
index 23fe3f302a0d67292c7a526cc8378cfd1df2232f..e04d3cea9e5cec4b6ef22933908407df9b81f4e5 100644 (file)
@@ -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 (file)
index 0000000..d7895b3
--- /dev/null
@@ -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 { }
+  };
+}