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
This commit is contained in:
parent
752b81d9c7
commit
a26780a30a
@ -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
|
||||
|
142
gcc/cp/pt.c
142
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)
|
||||
{
|
||||
|
8
gcc/testsuite/g++.dg/template/non-deducible1.C
Normal file
8
gcc/testsuite/g++.dg/template/non-deducible1.C
Normal file
@ -0,0 +1,8 @@
|
||||
// PR c++/23055
|
||||
|
||||
template <class> struct S { typedef int type; };
|
||||
|
||||
template <class T>
|
||||
int foo(T, typename S<T>::type * ret);
|
||||
|
||||
int j = foo(1, 0);
|
@ -7,7 +7,7 @@ template<const A* a> class C {};
|
||||
template<const B* b> class D {};
|
||||
template<B* b> class E {};
|
||||
|
||||
template<const B* b> void f(D<b> &, C<static_cast<const A*>(b)> &) {} // { dg-error "" "" { target c++98 } }
|
||||
template<const B* b> void f(D<b> &, C<static_cast<const A*>(b)> &) {} // { dg-error "" "" }
|
||||
template<const B* b> void g(D<b> &, E<const_cast<B*>(b)> &) {} // { dg-error "" "" { target c++98 } }
|
||||
|
||||
B b;
|
||||
|
Loading…
x
Reference in New Issue
Block a user