diff options
author | Jason Merrill <jason@redhat.com> | 2013-04-11 09:17:54 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2013-04-11 09:17:54 -0400 |
commit | a26780a30a985778bcd772a6bf7bc217f7cc4b00 (patch) | |
tree | 9fda50c9999e171eb1f653158f73481fa4b9c423 /gcc/cp | |
parent | 752b81d9c7c4bd1ee5136874ae0852a0127cc373 (diff) | |
download | gcc-a26780a30a985778bcd772a6bf7bc217f7cc4b00.zip gcc-a26780a30a985778bcd772a6bf7bc217f7cc4b00.tar.gz gcc-a26780a30a985778bcd772a6bf7bc217f7cc4b00.tar.bz2 |
re PR c++/23055 (overload resolution does not find templated function (zero -> pointer))
PR c++/23055
* pt.c (uses_deducible_template_parms): New.
(deducible_array_bound, deducible_expression): New.
(deducible_template_args): New.
(unify_one_argument): Call uses_deducible_template_parms.
From-SVN: r197790
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/pt.c | 142 |
2 files changed, 149 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 01fc3ef..f1cf2ce 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2013-04-11 Jason Merrill <jason@redhat.com> + + PR c++/23055 + * pt.c (uses_deducible_template_parms): New. + (deducible_array_bound, deducible_expression): New. + (deducible_template_args): New. + (unify_one_argument): Call uses_deducible_template_parms. + 2013-04-11 Paolo Carlini <paolo.carlini@oracle.com> PR c++/56913 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1d429fe..5bb0cc0 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -15357,6 +15357,135 @@ check_non_deducible_conversion (tree parm, tree arg, int strict, return unify_arg_conversion (explain_p, parm, type, arg); } +static bool uses_deducible_template_parms (tree type); + +/* Returns true iff the expression EXPR is one from which a template + argument can be deduced. In other words, if it's an undecorated + use of a template non-type parameter. */ + +static bool +deducible_expression (tree expr) +{ + return (TREE_CODE (expr) == TEMPLATE_PARM_INDEX); +} + +/* Returns true iff the array domain DOMAIN uses a template parameter in a + deducible way; that is, if it has a max value of <PARM> - 1. */ + +static bool +deducible_array_bound (tree domain) +{ + if (domain == NULL_TREE) + return false; + + tree max = TYPE_MAX_VALUE (domain); + if (TREE_CODE (max) != MINUS_EXPR) + return false; + + return deducible_expression (TREE_OPERAND (max, 0)); +} + +/* Returns true iff the template arguments ARGS use a template parameter + in a deducible way. */ + +static bool +deducible_template_args (tree args) +{ + for (int i = 0; i < TREE_VEC_LENGTH (args); ++i) + { + bool deducible; + tree elt = TREE_VEC_ELT (args, i); + if (ARGUMENT_PACK_P (elt)) + deducible = deducible_template_args (ARGUMENT_PACK_ARGS (elt)); + else + { + if (PACK_EXPANSION_P (elt)) + elt = PACK_EXPANSION_PATTERN (elt); + if (TREE_CODE (elt) == TEMPLATE_TEMPLATE_PARM) + deducible = true; + else if (TYPE_P (elt)) + deducible = uses_deducible_template_parms (elt); + else + deducible = deducible_expression (elt); + } + if (deducible) + return true; + } + return false; +} + +/* Returns true iff TYPE contains any deducible references to template + parameters, as per 14.8.2.5. */ + +static bool +uses_deducible_template_parms (tree type) +{ + if (PACK_EXPANSION_P (type)) + type = PACK_EXPANSION_PATTERN (type); + + /* T + cv-list T + TT<T> + TT<i> + TT<> */ + if (TREE_CODE (type) == TEMPLATE_TYPE_PARM + || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM) + return true; + + /* T* + T& + T&& */ + if (POINTER_TYPE_P (type)) + return uses_deducible_template_parms (TREE_TYPE (type)); + + /* T[integer-constant ] + type [i] */ + if (TREE_CODE (type) == ARRAY_TYPE) + return (uses_deducible_template_parms (TREE_TYPE (type)) + || deducible_array_bound (TYPE_DOMAIN (type))); + + /* T type ::* + type T::* + T T::* + T (type ::*)() + type (T::*)() + type (type ::*)(T) + type (T::*)(T) + T (type ::*)(T) + T (T::*)() + T (T::*)(T) */ + if (TYPE_PTRMEM_P (type)) + return (uses_deducible_template_parms (TYPE_PTRMEM_CLASS_TYPE (type)) + || (uses_deducible_template_parms + (TYPE_PTRMEM_POINTED_TO_TYPE (type)))); + + /* template-name <T> (where template-name refers to a class template) + template-name <i> (where template-name refers to a class template) */ + if (CLASS_TYPE_P (type) + && CLASSTYPE_TEMPLATE_INFO (type) + && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))) + return deducible_template_args (INNERMOST_TEMPLATE_ARGS + (CLASSTYPE_TI_ARGS (type))); + + /* type (T) + T() + T(T) */ + if (TREE_CODE (type) == FUNCTION_TYPE + || TREE_CODE (type) == METHOD_TYPE) + { + if (uses_deducible_template_parms (TREE_TYPE (type))) + return true; + tree parm = TYPE_ARG_TYPES (type); + if (TREE_CODE (type) == METHOD_TYPE) + parm = TREE_CHAIN (parm); + for (; parm; parm = TREE_CHAIN (parm)) + if (uses_deducible_template_parms (TREE_VALUE (parm))) + return true; + } + + return false; +} + /* Subroutine of type_unification_real and unify_pack_expansion to handle unification of a single P/A pair. Parameters are as for those functions. */ @@ -15376,10 +15505,21 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg, template args from other function args. */ return unify_success (explain_p); - /* FIXME uses_deducible_template_parms */ + /* Implicit conversions (Clause 4) will be performed on a function + argument to convert it to the type of the corresponding function + parameter if the parameter type contains no template-parameters that + participate in template argument deduction. */ if (TYPE_P (parm) && !uses_template_parms (parm)) + /* For function parameters that contain no template-parameters at all, + we have historically checked for convertibility in order to shortcut + consideration of this candidate. */ return check_non_deducible_conversion (parm, arg, strict, flags, explain_p); + else if (strict == DEDUCE_CALL + && TYPE_P (parm) && !uses_deducible_template_parms (parm)) + /* For function parameters with only non-deducible template parameters, + just return. */ + return unify_success (explain_p); switch (strict) { |