diff options
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index bb93047..f829095 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -93,7 +93,7 @@ static void pop_access_scope (tree); static int resolve_overloaded_unification (tree, tree, tree, tree, unification_kind_t, int); static int try_one_overload (tree, tree, tree, tree, tree, - unification_kind_t, int); + unification_kind_t, int, bool); static int unify (tree, tree, tree, tree, int); static void add_pending_template (tree); static void reopen_tinst_level (tree); @@ -8924,9 +8924,15 @@ resolve_overloaded_unification (tree tparms, { 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 @@ -8962,10 +8968,8 @@ resolve_overloaded_unification (tree tparms, 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); } } } @@ -8973,14 +8977,9 @@ resolve_overloaded_unification (tree tparms, || 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 (); @@ -9009,6 +9008,9 @@ resolve_overloaded_unification (tree tparms, /* 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 @@ -9018,7 +9020,8 @@ try_one_overload (tree tparms, tree parm, tree arg, unification_kind_t strict, - int sub_strict) + int sub_strict, + bool addr_p) { int nargs; tree tempargs; @@ -9034,6 +9037,11 @@ try_one_overload (tree tparms, 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 |