summaryrefslogtreecommitdiff
path: root/contrib/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/pt.c')
-rw-r--r--contrib/gcc/cp/pt.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c
index 62a66d34ea2a..64d44284d006 100644
--- a/contrib/gcc/cp/pt.c
+++ b/contrib/gcc/cp/pt.c
@@ -95,7 +95,7 @@ static void pop_access_scope PARAMS ((tree));
static int resolve_overloaded_unification PARAMS ((tree, tree, tree, tree,
unification_kind_t, int));
static int try_one_overload PARAMS ((tree, tree, tree, tree, tree,
- unification_kind_t, int));
+ unification_kind_t, int, bool));
static int unify PARAMS ((tree, tree, tree, tree, int));
static void add_pending_template PARAMS ((tree));
static void reopen_tinst_level PARAMS ((tree));
@@ -3991,7 +3991,8 @@ lookup_template_function (fns, arglist)
if (fns == error_mark_node || arglist == error_mark_node)
return error_mark_node;
- if (fns == NULL_TREE)
+ if (fns == NULL_TREE
+ || TREE_CODE (fns) == FUNCTION_DECL)
{
error ("non-template used as template");
return error_mark_node;
@@ -8437,9 +8438,15 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict,
{
tree tempargs = copy_node (targs);
int good = 0;
+ bool addr_p;
if (TREE_CODE (arg) == ADDR_EXPR)
- arg = TREE_OPERAND (arg, 0);
+ {
+ arg = TREE_OPERAND (arg, 0);
+ addr_p = true;
+ }
+ else
+ addr_p = false;
if (TREE_CODE (arg) == COMPONENT_REF)
/* Handle `&x' where `x' is some static or non-static member
@@ -8475,10 +8482,8 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict,
if (subargs)
{
elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE);
- if (TREE_CODE (elem) == METHOD_TYPE)
- elem = build_ptrmemfunc_type (build_pointer_type (elem));
- good += try_one_overload (tparms, targs, tempargs, parm, elem,
- strict, sub_strict);
+ good += try_one_overload (tparms, targs, tempargs, parm,
+ elem, strict, sub_strict, addr_p);
}
}
}
@@ -8486,14 +8491,9 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict,
|| TREE_CODE (arg) == FUNCTION_DECL)
{
for (; arg; arg = OVL_NEXT (arg))
- {
- tree type = TREE_TYPE (OVL_CURRENT (arg));
- if (TREE_CODE (type) == METHOD_TYPE)
- type = build_ptrmemfunc_type (build_pointer_type (type));
- good += try_one_overload (tparms, targs, tempargs, parm,
- type,
- strict, sub_strict);
- }
+ good += try_one_overload (tparms, targs, tempargs, parm,
+ TREE_TYPE (OVL_CURRENT (arg)),
+ strict, sub_strict, addr_p);
}
else
abort ();
@@ -8522,14 +8522,20 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict,
/* Subroutine of resolve_overloaded_unification; does deduction for a single
overload. Fills TARGS with any deduced arguments, or error_mark_node if
different overloads deduce different arguments for a given parm.
+ ADDR_P is true if the expression for which deduction is being
+ performed was of the form "& fn" rather than simply "fn".
+
Returns 1 on success. */
static int
-try_one_overload (tparms, orig_targs, targs, parm, arg, strict,
- sub_strict)
- tree tparms, orig_targs, targs, parm, arg;
- unification_kind_t strict;
- int sub_strict;
+try_one_overload (tree tparms,
+ tree orig_targs,
+ tree targs,
+ tree parm,
+ tree arg,
+ unification_kind_t strict,
+ int sub_strict,
+ bool addr_p)
{
int nargs;
tree tempargs;
@@ -8545,6 +8551,11 @@ try_one_overload (tparms, orig_targs, targs, parm, arg, strict,
if (uses_template_parms (arg))
return 1;
+ if (TREE_CODE (arg) == METHOD_TYPE)
+ arg = build_ptrmemfunc_type (build_pointer_type (arg));
+ else if (addr_p)
+ arg = build_pointer_type (arg);
+
sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
/* We don't copy orig_targs for this because if we have already deduced