Commit 86771dcb by Jason Merrill Committed by Jason Merrill

PR c++/78489 - wrong SFINAE behavior.

	PR c++/84489
	* pt.c (type_unification_real): Don't defer substitution failure.

From-SVN: r258824
parent 532c7a45
2018-03-23 Jason Merrill <jason@redhat.com>
PR c++/78489 - wrong SFINAE behavior.
PR c++/84489
* pt.c (type_unification_real): Don't defer substitution failure.
2018-03-23 Jakub Jelinek <jakub@redhat.com>
PR c++/85015
......
......@@ -19995,41 +19995,49 @@ type_unification_real (tree tparms,
if (targ || tparm == error_mark_node)
continue;
tree parm = TREE_VALUE (tparm);
tsubst_flags_t fcomplain = complain;
if (saw_undeduced == 1)
{
/* When saw_undeduced == 1, substitution into parm and arg might
fail or not replace all template parameters, and that's
fine. */
fcomplain = tf_none;
if (TREE_CODE (parm) == PARM_DECL
&& uses_template_parms (TREE_TYPE (parm)))
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);
if (saw_undeduced == 1)
++processing_template_decl;
arg = tsubst_template_arg (arg, full_targs, fcomplain, NULL_TREE);
if (saw_undeduced == 1)
--processing_template_decl;
if (arg != error_mark_node && !uses_template_parms (arg))
arg = convert_template_argument (parm, arg, full_targs, complain,
i, NULL_TREE);
else if (saw_undeduced == 1)
arg = NULL_TREE;
if (saw_undeduced == 1
&& TREE_CODE (parm) == PARM_DECL
&& uses_template_parms (TREE_TYPE (parm)))
{
/* The type of this non-type parameter depends on undeduced
parameters. Don't try to use its default argument yet,
but do check whether the arguments we already have cause
substitution failure, so that that happens before we try
later default arguments (78489). */
tree type = tsubst (TREE_TYPE (parm), full_targs, complain,
NULL_TREE);
if (type == error_mark_node)
arg = error_mark_node;
else
arg = NULL_TREE;
}
else
arg = error_mark_node;
{
arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE);
if (!uses_template_parms (arg))
arg = convert_template_argument (parm, arg, full_targs,
complain, i, NULL_TREE);
else if (saw_undeduced == 1)
arg = NULL_TREE;
else
arg = error_mark_node;
}
if (saw_undeduced == 1)
--processing_template_decl;
input_location = save_loc;
*checks = get_deferred_access_checks ();
pop_deferring_access_checks ();
if (arg == error_mark_node)
return 1;
else if (arg)
......
// PR c++/55724
// { dg-do compile { target c++11 } }
template<int N> struct S {};
template<typename T = int, T N = 42> void f(S<N>) {}
int main() { S<1> s; f(s); }
// PR c++/78489
// { dg-do compile { target c++11 } }
template <bool P, class T = void> struct enable_if { using type = T; };
template <class T> struct enable_if<false, T> {};
template <class Dummy> struct use_type { using type = int; };
template <bool Pred>
struct get_type {
static_assert(Pred, "");
using type = int;
};
template <bool Val,
class = typename enable_if<Val>::type, // Evaluation/Substitution should end here
class ValT = typename get_type<Val>::type, // This should not be instantiated
typename use_type<ValT>::type = 0 // This NTTP causes ValT to be required
>
constexpr bool test(int) { return false; }
template <bool>
constexpr bool test(long) { return true; }
static_assert(test<false>(0), ""); // should call test(long)
// PR c++/78489
// { dg-do compile { target c++11 } }
template <bool Pred, class T> struct enable_if { typedef T type; };
template <class T> struct enable_if<false, T> {};
template <int Idx> struct blows_up { static_assert(Idx != Idx, ""); };
template <int Idx,
// substitution should fail here
typename enable_if<Idx != Idx, int>::type = 0,
// GCC evaluates this statement
class = typename blows_up<Idx>::type
>
void Foo() {}
// Check the constructor in as SFINAE context
template <int I> constexpr auto test(int) -> decltype((Foo<I>(), true)) { return true; }
template <int> constexpr bool test(long) { return false; }
static_assert(!test<3>(0), ""); // Blows up
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment