diff options
Diffstat (limited to 'contrib/gcc/cp/pt.c')
-rw-r--r-- | contrib/gcc/cp/pt.c | 51 |
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 |