re PR c++/59759 (internal compiler error: in unify, using std::enable_if on classes)

PR c++/59759
	* pt.c (convert_template_argument): Handle VAR_DECL properly.

From-SVN: r232580
This commit is contained in:
Jason Merrill 2016-01-19 14:00:21 -05:00 committed by Jason Merrill
parent a88d10cb99
commit 33f4884259
4 changed files with 74 additions and 6 deletions

View File

@ -1,3 +1,8 @@
2016-01-19 Jason Merrill <jason@redhat.com>
PR c++/59759
* pt.c (convert_template_argument): Handle VAR_DECL properly.
2016-01-19 Marek Polacek <polacek@redhat.com>
PR c++/68586

View File

@ -19928,11 +19928,20 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
return unify_template_argument_mismatch (explain_p, parm, arg);
case VAR_DECL:
/* A non-type template parameter that is a variable should be a
an integral constant, in which case, it whould have been
folded into its (constant) value. So we should not be getting
a variable here. */
gcc_unreachable ();
/* We might get a variable as a non-type template argument in parm if the
corresponding parameter is type-dependent. Make any necessary
adjustments based on whether arg is a reference. */
if (CONSTANT_CLASS_P (arg))
parm = fold_non_dependent_expr (parm);
else if (REFERENCE_REF_P (arg))
{
tree sub = TREE_OPERAND (arg, 0);
STRIP_NOPS (sub);
if (TREE_CODE (sub) == ADDR_EXPR)
arg = TREE_OPERAND (sub, 0);
}
/* Now use the normal expression code to check whether they match. */
goto expr;
case TYPE_ARGUMENT_PACK:
case NONTYPE_ARGUMENT_PACK:
@ -19965,7 +19974,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
if (is_overloaded_fn (parm) || type_unknown_p (parm))
return unify_success (explain_p);
gcc_assert (EXPR_P (parm));
expr:
/* We must be looking at an expression. This can happen with
something like:

View File

@ -0,0 +1,27 @@
// PR c++/59759
// { dg-do compile { target c++11 } }
namespace std {
template <typename _Tp>
struct B {
static constexpr _Tp value = 0;
};
typedef B<int> false_type;
struct C : false_type {};
template <typename>
struct is_integral : C {};
template <int, typename _Tp>
struct enable_if {
typedef _Tp type;
};
}
enum class enabled;
extern constexpr enabled dummy{};
template <typename T, typename std::enable_if<std::is_integral<T>::value,
T>::type = dummy>
class A;
template <typename T>
void f(A<const T&>*) {
A<const enabled&>* map;
f(map);
}

View File

@ -0,0 +1,27 @@
// PR c++/59759
// { dg-do compile { target c++11 } }
namespace std {
template <typename _Tp>
struct B {
static constexpr _Tp value = 0;
};
typedef B<int> false_type;
struct C : false_type {};
template <typename>
struct is_integral : C {};
template <int, typename _Tp>
struct enable_if {
typedef _Tp type;
};
}
enum class enabled;
constexpr enabled dummy{};
template <typename T, typename std::enable_if<std::is_integral<T>::value,
enabled>::type = dummy>
class A;
template <typename T>
void f(A<T>*) {
A<int>* map;
f(map);
}