On Wed, Mar 7, 2018 at 12:18 PM, Paolo Carlini <paolo.carl...@oracle.com> wrote: > Hi, > > [snip the various clarifications] > > Il 7 Marzo 2018 17:57:07 CET, Jason Merrill <ja...@redhat.com> ha scritto: >>My thought was that this patch adds a lot of managing of the flag in >>different places in the parser, whereas looking for error_mark_node in >>the template parms here would be just in one place. But if you prefer >>the current approach, that's fine, it's straightforward enough. > > Thanks a lot for the various clarifications above, where essentially turns > out that some details of my patch are correct essentially by chance ;) > Seriously, I'm thinking the following: since 8 is getting real close, what > if, for 8, for the known mild regressions, we go ahead with my super safe > Plan B which I mentioned at beginning of the thread, then as soon as trunk > branches we immediately apply my patch and we give it a serious spin, say we > rebuild distros with it, and see what happens?
This is what I was suggesting, what do you think?
commit 706f372b52e65694161b9dff0272481d23fa898a Author: Jason Merrill <ja...@redhat.com> Date: Wed Mar 7 14:45:19 2018 -0500 PR c++/71832 - ICE with ill-formed template parameter. * pt.c (any_erroneous_template_args_p): New. * parser.c (cp_parser_class_specifier_1): Use it. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 268be0fd543..8f3ec86e8ce 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6558,6 +6558,7 @@ extern int processing_template_parmlist; extern bool dependent_type_p (tree); extern bool dependent_scope_p (tree); extern bool any_dependent_template_arguments_p (const_tree); +extern bool any_erroneous_template_args_p (const_tree); extern bool dependent_template_p (tree); extern bool dependent_template_id_p (tree, tree); extern bool type_dependent_expression_p (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a19bbe1e1d0..f7a8be50b79 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -22682,6 +22682,8 @@ cp_parser_class_specifier_1 (cp_parser* parser) FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_default_args, ix, e) { decl = e->decl; + if (any_erroneous_template_args_p (decl)) + continue; /* If there are default arguments that have not yet been processed, take care of them now. */ if (class_type != e->class_type) @@ -22704,6 +22706,8 @@ cp_parser_class_specifier_1 (cp_parser* parser) save_ccr = current_class_ref; FOR_EACH_VEC_SAFE_ELT (unparsed_nsdmis, ix, decl) { + if (any_erroneous_template_args_p (decl)) + continue; if (class_type != DECL_CONTEXT (decl)) { if (pushed_scope) @@ -27642,6 +27646,9 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function) if (DECL_FUNCTION_TEMPLATE_P (member_function)) member_function = DECL_TEMPLATE_RESULT (member_function); + if (any_erroneous_template_args_p (member_function)) + return; + /* There should not be any class definitions in progress at this point; the bodies of members are only parsed outside of all class definitions. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 89024c10fe2..1ce04aaabc7 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -25048,6 +25048,38 @@ any_dependent_template_arguments_p (const_tree args) return false; } +/* Returns true if ARGS contains any errors. */ + +bool +any_erroneous_template_args_p (const_tree args) +{ + int i; + int j; + + if (args && TREE_CODE (args) != TREE_VEC) + { + if (tree ti = get_template_info (args)) + args = TI_ARGS (ti); + else + args = NULL_TREE; + } + + if (!args) + return false; + if (args == error_mark_node) + return true; + + for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i) + { + const_tree level = TMPL_ARGS_LEVEL (args, i + 1); + for (j = 0; j < TREE_VEC_LENGTH (level); ++j) + if (error_operand_p (TREE_VEC_ELT (level, j))) + return true; + } + + return false; +} + /* Returns TRUE if the template TMPL is type-dependent. */ bool