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:
parent
a88d10cb99
commit
33f4884259
@ -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
|
||||
|
21
gcc/cp/pt.c
21
gcc/cp/pt.c
@ -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:
|
||||
|
||||
|
27
gcc/testsuite/g++.dg/cpp0x/temp_default6.C
Normal file
27
gcc/testsuite/g++.dg/cpp0x/temp_default6.C
Normal 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);
|
||||
}
|
27
gcc/testsuite/g++.dg/cpp0x/temp_default7.C
Normal file
27
gcc/testsuite/g++.dg/cpp0x/temp_default7.C
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user