+2018-03-21 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/84610
+ PR c++/84642
+ * parser.c (abort_fully_implicit_template_p): New.
+ (cp_parser_skip_to_end_of_statement): Use it.
+ (cp_parser_skip_to_end_of_block_or_statement): Likewise.
+ (finish_fully_implicit_template_p): Clear
+ implicit_template_parms and implicit_template_scope.
+
2018-03-21 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/84972
(cp_parser *, tree);
static tree finish_fully_implicit_template
(cp_parser *, tree);
+static void abort_fully_implicit_template
+ (cp_parser *);
/* Classes [gram.class] */
/* Unwind generic function template scope if necessary. */
if (parser->fully_implicit_function_template_p)
- finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
+ abort_fully_implicit_template (parser);
while (true)
{
/* Unwind generic function template scope if necessary. */
if (parser->fully_implicit_function_template_p)
- finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
+ abort_fully_implicit_template (parser);
while (nesting_depth >= 0)
{
end_template_decl ();
parser->fully_implicit_function_template_p = false;
+ parser->implicit_template_parms = 0;
+ parser->implicit_template_scope = 0;
--parser->num_template_parameter_lists;
return member_decl_opt;
}
+/* Like finish_fully_implicit_template, but to be used in error
+ recovery, rearranging scopes so that we restore the state we had
+ before synthesize_implicit_template_parm inserted the implement
+ template parms scope. */
+
+static void
+abort_fully_implicit_template (cp_parser *parser)
+{
+ cp_binding_level *return_to_scope = current_binding_level;
+
+ if (parser->implicit_template_scope
+ && return_to_scope != parser->implicit_template_scope)
+ {
+ cp_binding_level *child = return_to_scope;
+ for (cp_binding_level *scope = child->level_chain;
+ scope != parser->implicit_template_scope;
+ scope = child->level_chain)
+ child = scope;
+ child->level_chain = parser->implicit_template_scope->level_chain;
+ parser->implicit_template_scope->level_chain = return_to_scope;
+ current_binding_level = parser->implicit_template_scope;
+ }
+ else
+ return_to_scope = return_to_scope->level_chain;
+
+ finish_fully_implicit_template (parser, NULL);
+
+ gcc_assert (current_binding_level == return_to_scope);
+}
+
/* Helper function for diagnostics that have complained about things
being used with 'extern "C"' linkage.