mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-05 13:41:18 +08:00
DR 1391
DR 1391 * pt.c (type_unification_real): Check convertibility here. (unify_one_argument): Not here. From-SVN: r223301
This commit is contained in:
parent
8f56fadc24
commit
c4d6d7bc46
@ -1,5 +1,9 @@
|
||||
2015-05-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
DR 1391
|
||||
* pt.c (type_unification_real): Check convertibility here.
|
||||
(unify_one_argument): Not here.
|
||||
|
||||
* tree.c (strip_typedefs_expr) [TRAIT_EXPR]: Fix typo.
|
||||
(strip_typedefs) [DECLTYPE_TYPE]: Fix typedef of decltype.
|
||||
[TREE_LIST]: Fix no-change case.
|
||||
|
134
gcc/cp/pt.c
134
gcc/cp/pt.c
@ -16678,7 +16678,7 @@ uses_deducible_template_parms (tree type)
|
||||
|
||||
static int
|
||||
unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
|
||||
int subr, unification_kind_t strict, int flags,
|
||||
int subr, unification_kind_t strict,
|
||||
bool explain_p)
|
||||
{
|
||||
tree arg_expr = NULL_TREE;
|
||||
@ -16695,16 +16695,10 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
|
||||
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. */
|
||||
if (strict != DEDUCE_EXACT
|
||||
&& TYPE_P (parm) && !uses_deducible_template_parms (parm))
|
||||
/* For function parameters with no deducible template parameters,
|
||||
just return. We'll check non-dependent conversions later. */
|
||||
return unify_success (explain_p);
|
||||
|
||||
switch (strict)
|
||||
@ -16843,7 +16837,7 @@ type_unification_real (tree tparms,
|
||||
++ia;
|
||||
|
||||
if (unify_one_argument (tparms, targs, parm, arg, subr, strict,
|
||||
flags, explain_p))
|
||||
explain_p))
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -16925,8 +16919,11 @@ type_unification_real (tree tparms,
|
||||
this parameter can be deduced. */
|
||||
if (TREE_CODE (tparm) == PARM_DECL
|
||||
&& uses_template_parms (TREE_TYPE (tparm))
|
||||
&& !saw_undeduced++)
|
||||
goto again;
|
||||
&& saw_undeduced < 2)
|
||||
{
|
||||
saw_undeduced = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Core issue #226 (C++0x) [temp.deduct]:
|
||||
|
||||
@ -16937,32 +16934,9 @@ type_unification_real (tree tparms,
|
||||
be NULL_TREE or ERROR_MARK_NODE, so we do not need
|
||||
to explicitly check cxx_dialect here. */
|
||||
if (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)))
|
||||
{
|
||||
tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
|
||||
tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i));
|
||||
reopen_deferring_access_checks (*checks);
|
||||
location_t save_loc = input_location;
|
||||
if (DECL_P (parm))
|
||||
input_location = DECL_SOURCE_LOCATION (parm);
|
||||
arg = tsubst_template_arg (arg, targs, complain, NULL_TREE);
|
||||
arg = convert_template_argument (parm, arg, targs, complain,
|
||||
i, NULL_TREE);
|
||||
input_location = save_loc;
|
||||
*checks = get_deferred_access_checks ();
|
||||
pop_deferring_access_checks ();
|
||||
if (arg == error_mark_node)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
TREE_VEC_ELT (targs, i) = arg;
|
||||
/* The position of the first default template argument,
|
||||
is also the number of non-defaulted arguments in TARGS.
|
||||
Record that. */
|
||||
if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
|
||||
SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* OK, there is a default argument. Wait until after the
|
||||
conversion check to do substitution. */
|
||||
continue;
|
||||
|
||||
/* If the type parameter is a parameter pack, then it will
|
||||
be deduced to an empty parameter pack. */
|
||||
@ -16987,6 +16961,84 @@ type_unification_real (tree tparms,
|
||||
|
||||
return unify_parameter_deduction_failure (explain_p, tparm);
|
||||
}
|
||||
|
||||
/* DR 1391: All parameters have args, now check non-dependent parms for
|
||||
convertibility. */
|
||||
if (saw_undeduced < 2)
|
||||
for (ia = 0, parms = xparms, args = xargs, nargs = xnargs;
|
||||
parms && parms != void_list_node && ia < nargs; )
|
||||
{
|
||||
parm = TREE_VALUE (parms);
|
||||
|
||||
if (TREE_CODE (parm) == TYPE_PACK_EXPANSION
|
||||
&& (!TREE_CHAIN (parms)
|
||||
|| TREE_CHAIN (parms) == void_list_node))
|
||||
/* For a function parameter pack that occurs at the end of the
|
||||
parameter-declaration-list, the type A of each remaining
|
||||
argument of the call is compared with the type P of the
|
||||
declarator-id of the function parameter pack. */
|
||||
break;
|
||||
|
||||
parms = TREE_CHAIN (parms);
|
||||
|
||||
if (TREE_CODE (parm) == TYPE_PACK_EXPANSION)
|
||||
/* For a function parameter pack that does not occur at the
|
||||
end of the parameter-declaration-list, the type of the
|
||||
parameter pack is a non-deduced context. */
|
||||
continue;
|
||||
|
||||
arg = args[ia];
|
||||
++ia;
|
||||
|
||||
if (uses_template_parms (parm))
|
||||
continue;
|
||||
if (check_non_deducible_conversion (parm, arg, strict, flags,
|
||||
explain_p))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Now substitute into the default template arguments. */
|
||||
for (i = 0; i < ntparms; i++)
|
||||
{
|
||||
tree targ = TREE_VEC_ELT (targs, i);
|
||||
tree tparm = TREE_VEC_ELT (tparms, i);
|
||||
|
||||
if (targ || tparm == error_mark_node)
|
||||
continue;
|
||||
tree parm = TREE_VALUE (tparm);
|
||||
|
||||
if (TREE_CODE (parm) == PARM_DECL
|
||||
&& uses_template_parms (TREE_TYPE (parm))
|
||||
&& saw_undeduced < 2)
|
||||
continue;
|
||||
|
||||
tree arg = TREE_PURPOSE (tparm);
|
||||
reopen_deferring_access_checks (*checks);
|
||||
location_t save_loc = input_location;
|
||||
if (DECL_P (parm))
|
||||
input_location = DECL_SOURCE_LOCATION (parm);
|
||||
arg = tsubst_template_arg (arg, targs, complain, NULL_TREE);
|
||||
arg = convert_template_argument (parm, arg, targs, complain,
|
||||
i, NULL_TREE);
|
||||
input_location = save_loc;
|
||||
*checks = get_deferred_access_checks ();
|
||||
pop_deferring_access_checks ();
|
||||
if (arg == error_mark_node)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
TREE_VEC_ELT (targs, i) = arg;
|
||||
/* The position of the first default template argument,
|
||||
is also the number of non-defaulted arguments in TARGS.
|
||||
Record that. */
|
||||
if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
|
||||
SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (saw_undeduced++ == 1)
|
||||
goto again;
|
||||
}
|
||||
#ifdef ENABLE_CHECKING
|
||||
if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
|
||||
@ -17601,7 +17653,7 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
|
||||
|
||||
/* Unify the pattern with the current argument. */
|
||||
if (unify_one_argument (tparms, targs, parm, arg, subr, strict,
|
||||
LOOKUP_IMPLICIT, explain_p))
|
||||
explain_p))
|
||||
return 1;
|
||||
|
||||
/* For each parameter pack, collect the deduced value. */
|
||||
|
@ -1,8 +1,7 @@
|
||||
// This should fail deduction, before it produces a candidate.
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
template <class... T>
|
||||
void f(T... ts); // { dg-message "deduction" }
|
||||
void f(T... ts);
|
||||
|
||||
struct B { };
|
||||
int main()
|
||||
|
17
gcc/testsuite/g++.dg/template/dr1391-1.C
Normal file
17
gcc/testsuite/g++.dg/template/dr1391-1.C
Normal file
@ -0,0 +1,17 @@
|
||||
// DR 1391
|
||||
|
||||
template<class T> struct A {
|
||||
typename T::N n;
|
||||
};
|
||||
template<class T> struct B { };
|
||||
|
||||
template<class T, class T2>
|
||||
void foo(const A<T>& r); // #1
|
||||
template<class T>
|
||||
void foo(const B<T>& r); // #2
|
||||
|
||||
void baz() {
|
||||
B<char> b;
|
||||
foo(b); // OK
|
||||
foo<char>(b); // error
|
||||
}
|
22
gcc/testsuite/g++.dg/template/dr1391-2.C
Normal file
22
gcc/testsuite/g++.dg/template/dr1391-2.C
Normal file
@ -0,0 +1,22 @@
|
||||
// DR 1391
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
template<class T>
|
||||
struct A {
|
||||
typename T::N n;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct B { };
|
||||
|
||||
template <class T, class... U>
|
||||
typename A<T>::value_t bar(int, T, U...);
|
||||
|
||||
template <class T>
|
||||
T bar(T, T);
|
||||
|
||||
void baz()
|
||||
{
|
||||
B<char> b;
|
||||
bar(b, b);
|
||||
}
|
13
gcc/testsuite/g++.dg/template/dr1391-3.C
Normal file
13
gcc/testsuite/g++.dg/template/dr1391-3.C
Normal file
@ -0,0 +1,13 @@
|
||||
// DR 1391
|
||||
|
||||
template <class T> struct Z {
|
||||
typedef typename T::x xx;
|
||||
};
|
||||
template <class T> typename Z<T>::xx f(void *, T);
|
||||
template <class T> void f(int, T);
|
||||
struct A {} a;
|
||||
int main() {
|
||||
f(1, a); // If the implementation rules out the first overload
|
||||
// because of the invalid conversion from int to void*,
|
||||
// the error instantiating Z<A> will be avoided
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user