diff options
author | Jason Merrill <jason@redhat.com> | 2016-01-19 14:00:21 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-01-19 14:00:21 -0500 |
commit | 33f488425964a50f8bcd847980c02beea8b25956 (patch) | |
tree | 5619684f985ef38c0ced0fa21b91f394c85a805c | |
parent | a88d10cb99e33d58fd07a4bad0ae7d523d731135 (diff) | |
download | gcc-33f488425964a50f8bcd847980c02beea8b25956.zip gcc-33f488425964a50f8bcd847980c02beea8b25956.tar.gz gcc-33f488425964a50f8bcd847980c02beea8b25956.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/pt.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/temp_default6.C | 27 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/temp_default7.C | 27 |
4 files changed, 74 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ac2bbae..45cb0e7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6062ebe..ae60f1c 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 0000000..10cde2d --- /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 <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); +} 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 0000000..c517aad --- /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 <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); +} |