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.
commit e60c343e7913ad2ff194c95391d6dd8fc479ce88 Author: Jason Merrill <ja...@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 { } + }; +}