aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-04-11 09:17:54 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-04-11 09:17:54 -0400
commita26780a30a985778bcd772a6bf7bc217f7cc4b00 (patch)
tree9fda50c9999e171eb1f653158f73481fa4b9c423 /gcc/cp
parent752b81d9c7c4bd1ee5136874ae0852a0127cc373 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/cp/pt.c142
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)
{