Hi again,
On 07/03/2018 21:49, Paolo Carlini wrote:
... If you ask my opinion, at the moment I still believe that the best
solution would be doing something at parsing time, save the
information, in a more elegant way, maybe adding a special "erroneous
TREE_VEC" flag to the TREE_VECs. I don't know exactly. Even better a
unique flag for all the template parameter lists of each class.
Just to explain more *concretely* what I had in mind, I quickly hacked
the below, which would be a *minimal* implementation of my idea. It
should be also possible to consolidate the flags of the various
TMPL_ARGS_LEVELs to the flag of the TREE_VEC returned by TI_ARGS
(get_template_info). That would be fantastic: ideally I would like to
see an O(0) any_erroneous_template_args_p. Maybe we can do that when we
use SET_TMPL_ARGS_LEVEL? Probably it would take you 5 mins to implement
all of that. Or, I was thinking, something completely different, instead
of fiddling with TREE_VECs, have something in DECL_TEMPLATE_INFO? (see
again my remark about the 5 mins ;)
Paolo.
//////////////////
Index: cp-tree.h
===================================================================
--- cp-tree.h (revision 258355)
+++ cp-tree.h (working copy)
@@ -592,6 +592,8 @@ struct GTY(()) ptrmem_cst {
};
typedef struct ptrmem_cst * ptrmem_cst_t;
+#define ERRONEOUS_TREE_VEC(NODE) ((NODE)->base.u.bits.lang_flag_0)
+
#define CLEANUP_P(NODE) TREE_LANG_FLAG_0 (TRY_BLOCK_CHECK (NODE))
#define BIND_EXPR_TRY_BLOCK(NODE) \
@@ -6558,6 +6560,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);
Index: parser.c
===================================================================
--- parser.c (revision 258355)
+++ parser.c (working copy)
@@ -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* pars
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. */
Index: pt.c
===================================================================
--- pt.c (revision 258355)
+++ pt.c (working copy)
@@ -4459,6 +4459,8 @@ end_template_parm_list (tree parms)
{
next = TREE_CHAIN (parm);
TREE_VEC_ELT (saved_parmlist, nparms) = parm;
+ if (error_operand_p (parm))
+ ERRONEOUS_TREE_VEC (saved_parmlist) = true;
TREE_CHAIN (parm) = NULL_TREE;
}
@@ -25048,6 +25050,42 @@ any_dependent_template_arguments_p (const_tree arg
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);
+ if (ERRONEOUS_TREE_VEC (level))
+ return true;
+ /*
+ 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