cp-tree.h (OVL_NESTED_P, [...]): New.
* cp-tree.h (OVL_NESTED_P, OVL_LOOKUP_P): New. (ovl_first): Move inline definition to end of file. (ovl_make, lookup_add): Declare. (get_fns, get_first_fn): Make pure. * tree.c (ovl_cache): New. (ovl_make, lookup_add): New. * pt.c (do_class_deduction): Don't add candidates that will be elided. From-SVN: r248121
This commit is contained in:
parent
a736411aca
commit
e09ae85766
4 changed files with 123 additions and 42 deletions
|
@ -1,7 +1,16 @@
|
|||
2017-05-16 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* cp-tree.h (OVL_NESTED_P, OVL_LOOKUP_P): New.
|
||||
(ovl_first): Move inline definition to end of file.
|
||||
(ovl_make, lookup_add): Declare.
|
||||
(get_fns, get_first_fn): Make pure.
|
||||
* tree.c (ovl_cache): New.
|
||||
(ovl_make, lookup_add): New.
|
||||
* pt.c (do_class_deduction): Don't add candidates that will be
|
||||
elided.
|
||||
|
||||
* call.c (build_user_type_conversion_1): Use OVL_FIRST.
|
||||
(print_error_for_call_faulure): Use OVL_NAME.
|
||||
(print_error_for_call_failure): Use OVL_NAME.
|
||||
(build_op_call_1): Use ovl_iterator.
|
||||
(add_candidates): Use OVL_FIRST & lkp_iterator.
|
||||
(build_op_delete_call): Use MAYBE_BASELINK_FUNCTIONS &
|
||||
|
|
|
@ -371,11 +371,13 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
|
|||
CALL_EXPR_ORDERED_ARGS (in CALL_EXPR, AGGR_INIT_EXPR)
|
||||
DECLTYPE_FOR_REF_CAPTURE (in DECLTYPE_TYPE)
|
||||
CONSTUCTOR_C99_COMPOUND_LITERAL (in CONSTRUCTOR)
|
||||
OVL_NESTED_P (in OVERLOAD)
|
||||
4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
|
||||
CALL_EXPR, or FIELD_DECL).
|
||||
IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE)
|
||||
DECL_TINFO_P (in VAR_DECL)
|
||||
FUNCTION_REF_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE)
|
||||
OVL_LOOKUP_P (in OVERLOAD)
|
||||
5: C_IS_RESERVED_WORD (in IDENTIFIER_NODE)
|
||||
DECL_VTABLE_OR_VTT_P (in VAR_DECL)
|
||||
FUNCTION_RVALUE_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE)
|
||||
|
@ -626,6 +628,11 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
|
|||
and can be freed afterward. */
|
||||
#define OVL_ARG_DEPENDENT(NODE) TREE_LANG_FLAG_0 (OVERLOAD_CHECK (NODE))
|
||||
|
||||
/* If set, this overload contains a nested overload. */
|
||||
#define OVL_NESTED_P(NODE) TREE_LANG_FLAG_3 (OVERLOAD_CHECK (NODE))
|
||||
/* If set, this overload was constructed during lookup. */
|
||||
#define OVL_LOOKUP_P(NODE) TREE_LANG_FLAG_4 (OVERLOAD_CHECK (NODE))
|
||||
|
||||
/* The first decl of an overload. */
|
||||
#define OVL_FIRST(NODE) ovl_first (NODE)
|
||||
/* The name of the overload set. */
|
||||
|
@ -6733,17 +6740,14 @@ extern tree hash_tree_cons (tree, tree, tree);
|
|||
extern tree hash_tree_chain (tree, tree);
|
||||
extern tree build_qualified_name (tree, tree, tree, bool);
|
||||
extern tree build_ref_qualified_type (tree, cp_ref_qualifier);
|
||||
inline tree
|
||||
ovl_first (tree node)
|
||||
{
|
||||
while (TREE_CODE (node) == OVERLOAD)
|
||||
node = OVL_FUNCTION (node);
|
||||
return node;
|
||||
}
|
||||
inline tree ovl_first (tree) ATTRIBUTE_PURE;
|
||||
extern tree ovl_make (tree fn,
|
||||
tree next = NULL_TREE);
|
||||
extern tree lookup_add (tree lookup, tree ovl);
|
||||
extern int is_overloaded_fn (tree);
|
||||
extern tree dependent_name (tree);
|
||||
extern tree get_fns (tree);
|
||||
extern tree get_first_fn (tree);
|
||||
extern tree get_fns (tree) ATTRIBUTE_PURE;
|
||||
extern tree get_first_fn (tree) ATTRIBUTE_PURE;
|
||||
extern tree ovl_cons (tree, tree);
|
||||
extern tree build_overload (tree, tree);
|
||||
extern tree ovl_scope (tree);
|
||||
|
@ -7188,6 +7192,16 @@ extern tree cp_ubsan_maybe_instrument_downcast (location_t, tree, tree, tree);
|
|||
extern tree cp_ubsan_maybe_instrument_cast_to_vbase (location_t, tree, tree);
|
||||
extern void cp_ubsan_maybe_initialize_vtbl_ptrs (tree);
|
||||
|
||||
/* Inline bodies. */
|
||||
|
||||
inline tree
|
||||
ovl_first (tree node)
|
||||
{
|
||||
while (TREE_CODE (node) == OVERLOAD)
|
||||
node = OVL_FUNCTION (node);
|
||||
return node;
|
||||
}
|
||||
|
||||
/* -- end of C++ */
|
||||
|
||||
#endif /* ! GCC_CP_TREE_H */
|
||||
|
|
76
gcc/cp/pt.c
76
gcc/cp/pt.c
|
@ -25157,9 +25157,29 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
|
|||
tree cands = lookup_qualified_name (CP_DECL_CONTEXT (tmpl), dname,
|
||||
/*type*/false, /*complain*/false,
|
||||
/*hidden*/false);
|
||||
bool elided = false;
|
||||
if (cands == error_mark_node)
|
||||
cands = NULL_TREE;
|
||||
|
||||
/* Prune explicit deduction guides in copy-initialization context. */
|
||||
if (flags & LOOKUP_ONLYCONVERTING)
|
||||
{
|
||||
for (lkp_iterator iter (cands); !elided && iter; ++iter)
|
||||
if (DECL_NONCONVERTING_P (STRIP_TEMPLATE (*iter)))
|
||||
elided = true;
|
||||
|
||||
if (elided)
|
||||
{
|
||||
/* Found a nonconverting guide, prune the candidates. */
|
||||
tree pruned = NULL_TREE;
|
||||
for (lkp_iterator iter (cands); iter; ++iter)
|
||||
if (!DECL_NONCONVERTING_P (STRIP_TEMPLATE (*iter)))
|
||||
pruned = lookup_add (pruned, *iter);
|
||||
|
||||
cands = pruned;
|
||||
}
|
||||
}
|
||||
|
||||
tree outer_args = NULL_TREE;
|
||||
if (DECL_CLASS_SCOPE_P (tmpl)
|
||||
&& CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (tmpl)))
|
||||
|
@ -25171,11 +25191,15 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
|
|||
bool saw_ctor = false;
|
||||
if (CLASSTYPE_METHOD_VEC (type))
|
||||
// FIXME cache artificial deduction guides
|
||||
for (tree fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns))
|
||||
for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (type));
|
||||
iter; ++iter)
|
||||
{
|
||||
tree fn = OVL_CURRENT (fns);
|
||||
tree guide = build_deduction_guide (fn, outer_args, complain);
|
||||
cands = ovl_cons (guide, cands);
|
||||
tree guide = build_deduction_guide (*iter, outer_args, complain);
|
||||
if ((flags & LOOKUP_ONLYCONVERTING)
|
||||
&& DECL_NONCONVERTING_P (STRIP_TEMPLATE (guide)))
|
||||
elided = true;
|
||||
else
|
||||
cands = lookup_add (cands, guide);
|
||||
|
||||
saw_ctor = true;
|
||||
}
|
||||
|
@ -25183,41 +25207,29 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
|
|||
if (!saw_ctor && args->length() == 0)
|
||||
{
|
||||
tree guide = build_deduction_guide (type, outer_args, complain);
|
||||
cands = ovl_cons (guide, cands);
|
||||
if ((flags & LOOKUP_ONLYCONVERTING)
|
||||
&& DECL_NONCONVERTING_P (STRIP_TEMPLATE (guide)))
|
||||
elided = true;
|
||||
else
|
||||
cands = lookup_add (cands, guide);
|
||||
}
|
||||
if (args->length() == 1)
|
||||
{
|
||||
tree guide = build_deduction_guide (build_reference_type (type),
|
||||
outer_args, complain);
|
||||
cands = ovl_cons (guide, cands);
|
||||
if ((flags & LOOKUP_ONLYCONVERTING)
|
||||
&& DECL_NONCONVERTING_P (STRIP_TEMPLATE (guide)))
|
||||
elided = true;
|
||||
else
|
||||
cands = lookup_add (cands, guide);
|
||||
}
|
||||
|
||||
/* Prune explicit deduction guides in copy-initialization context. */
|
||||
tree old_cands = cands;
|
||||
if (flags & LOOKUP_ONLYCONVERTING)
|
||||
if (elided && !cands)
|
||||
{
|
||||
tree t = cands;
|
||||
for (; t; t = OVL_NEXT (t))
|
||||
if (DECL_NONCONVERTING_P (STRIP_TEMPLATE (OVL_CURRENT (t))))
|
||||
break;
|
||||
if (t)
|
||||
{
|
||||
tree pruned = NULL_TREE;
|
||||
for (t = cands; t; t = OVL_NEXT (t))
|
||||
{
|
||||
tree f = OVL_CURRENT (t);
|
||||
if (!DECL_NONCONVERTING_P (STRIP_TEMPLATE (f)))
|
||||
pruned = build_overload (f, pruned);
|
||||
}
|
||||
cands = pruned;
|
||||
if (cands == NULL_TREE)
|
||||
{
|
||||
error ("cannot deduce template arguments for copy-initialization"
|
||||
" of %qT, as it has no non-explicit deduction guides or "
|
||||
"user-declared constructors", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
error ("cannot deduce template arguments for copy-initialization"
|
||||
" of %qT, as it has no non-explicit deduction guides or "
|
||||
"user-declared constructors", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
++cp_unevaluated_operand;
|
||||
|
@ -25227,7 +25239,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
|
|||
{
|
||||
error ("class template argument deduction failed:");
|
||||
t = build_new_function_call (cands, &args, complain | tf_decltype);
|
||||
if (old_cands != cands)
|
||||
if (elided)
|
||||
inform (input_location, "explicit deduction guides not considered "
|
||||
"for copy-initialization");
|
||||
}
|
||||
|
|
|
@ -2094,6 +2094,52 @@ build_ref_qualified_type (tree type, cp_ref_qualifier rqual)
|
|||
return t;
|
||||
}
|
||||
|
||||
/* Cache of free ovl nodes. Uses OVL_FUNCTION for chaining. */
|
||||
static GTY((deletable)) tree ovl_cache;
|
||||
|
||||
/* Make a raw overload node containing FN. */
|
||||
|
||||
tree
|
||||
ovl_make (tree fn, tree next)
|
||||
{
|
||||
tree result = ovl_cache;
|
||||
|
||||
if (result)
|
||||
{
|
||||
ovl_cache = OVL_FUNCTION (result);
|
||||
/* Zap the flags. */
|
||||
memset (result, 0, sizeof (tree_base));
|
||||
TREE_SET_CODE (result, OVERLOAD);
|
||||
}
|
||||
else
|
||||
result = make_node (OVERLOAD);
|
||||
|
||||
if (TREE_CODE (fn) == OVERLOAD)
|
||||
OVL_NESTED_P (result) = true;
|
||||
|
||||
TREE_TYPE (result) = (next || TREE_CODE (fn) == TEMPLATE_DECL
|
||||
? unknown_type_node : TREE_TYPE (fn));
|
||||
OVL_FUNCTION (result) = fn;
|
||||
OVL_CHAIN (result) = next;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Add a potential overload into a lookup set. */
|
||||
|
||||
tree
|
||||
lookup_add (tree lookup, tree ovl)
|
||||
{
|
||||
if (lookup || TREE_CODE (ovl) == TEMPLATE_DECL)
|
||||
{
|
||||
lookup = ovl_make (ovl, lookup);
|
||||
OVL_LOOKUP_P (lookup) = true;
|
||||
}
|
||||
else
|
||||
lookup = ovl;
|
||||
|
||||
return lookup;
|
||||
}
|
||||
|
||||
/* Returns nonzero if X is an expression for a (possibly overloaded)
|
||||
function. If "f" is a function or function template, "f", "c->f",
|
||||
"c.f", "C::f", and "f<int>" will all be considered possibly
|
||||
|
|
Loading…
Add table
Reference in a new issue