From 33f488425964a50f8bcd847980c02beea8b25956 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 19 Jan 2016 14:00:21 -0500 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 5 ++++ gcc/cp/pt.c | 21 ++++++++++++----- gcc/testsuite/g++.dg/cpp0x/temp_default6.C | 27 ++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/temp_default7.C | 27 ++++++++++++++++++++++ 4 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/temp_default6.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/temp_default7.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ac2bbae430f..45cb0e72a4c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2016-01-19 Jason Merrill + + PR c++/59759 + * pt.c (convert_template_argument): Handle VAR_DECL properly. + 2016-01-19 Marek Polacek PR c++/68586 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6062ebe50a6..ae60f1c2d0a 100644 --- a/gcc/cp/pt.c +++ b/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: diff --git a/gcc/testsuite/g++.dg/cpp0x/temp_default6.C b/gcc/testsuite/g++.dg/cpp0x/temp_default6.C new file mode 100644 index 00000000000..10cde2d0845 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/temp_default6.C @@ -0,0 +1,27 @@ +// PR c++/59759 +// { dg-do compile { target c++11 } } + +namespace std { +template +struct B { + static constexpr _Tp value = 0; +}; +typedef B false_type; +struct C : false_type {}; +template +struct is_integral : C {}; +template +struct enable_if { + typedef _Tp type; +}; +} +enum class enabled; +extern constexpr enabled dummy{}; +template ::value, + T>::type = dummy> +class A; +template +void f(A*) { + A* map; + f(map); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/temp_default7.C b/gcc/testsuite/g++.dg/cpp0x/temp_default7.C new file mode 100644 index 00000000000..c517aadb1fc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/temp_default7.C @@ -0,0 +1,27 @@ +// PR c++/59759 +// { dg-do compile { target c++11 } } + +namespace std { +template +struct B { + static constexpr _Tp value = 0; +}; +typedef B false_type; +struct C : false_type {}; +template +struct is_integral : C {}; +template +struct enable_if { + typedef _Tp type; +}; +} +enum class enabled; +constexpr enabled dummy{}; +template ::value, + enabled>::type = dummy> +class A; +template +void f(A*) { + A* map; + f(map); +} -- 2.30.2