diff options
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ42.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ43.C | 35 |
5 files changed, 67 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 986b942..e8d45dc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2015-08-06 Jason Merrill <jason@redhat.com> + + PR c++/67130 + PR c++/67131 + PR c++/66260 + * mangle.c (write_expression) [TEMPLATE_ID_EXPR]: Handle variable + templates. + * pt.c (tsubst_copy_and_build): Check for argument substitution + failure. + 2015-08-05 Jason Merrill <jason@redhat.com> * pt.c (determine_specialization): Print candidates after 'no diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index d471f4f..4518f20 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2822,7 +2822,9 @@ write_expression (tree expr) { tree fn = TREE_OPERAND (expr, 0); if (is_overloaded_fn (fn)) - fn = DECL_NAME (get_first_fn (fn)); + fn = get_first_fn (fn); + if (DECL_P (fn)) + fn = DECL_NAME (fn); if (IDENTIFIER_OPNAME_P (fn)) write_string ("on"); write_unqualified_id (fn); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 08fb2ff..c3bafd3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14752,6 +14752,8 @@ tsubst_copy_and_build (tree t, if (targs) targs = tsubst_template_args (targs, args, complain, in_decl); + if (targs == error_mark_node) + return error_mark_node; if (variable_template_p (templ)) { diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ42.C b/gcc/testsuite/g++.dg/cpp1y/var-templ42.C new file mode 100644 index 0000000..a43149d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ42.C @@ -0,0 +1,17 @@ +// PR c++/67131 +// { dg-do compile { target c++14 } } + +template <typename T> typename T::_ type; +template <template <typename...> class> struct A; +template <template <typename> class f> A<f> metafunction; +namespace detail { +template <typename> struct _decltype; +} +template <template <typename...> class F> struct A { + template <typename... T> + auto operator()() -> decltype(type<F<detail::_decltype<T>...>>); +}; +template <typename F> auto valid_call(F f) -> decltype(f()); +constexpr auto valid_call(...) { return 0; } +template <typename> struct no_type; +static_assert(!valid_call(metafunction<no_type>),""); // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ43.C b/gcc/testsuite/g++.dg/cpp1y/var-templ43.C new file mode 100644 index 0000000..414802f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ43.C @@ -0,0 +1,35 @@ +// PR c++/67130 +// { dg-do compile { target c++14 } } + +namespace std { +template <typename> struct __success_type; +template <typename> void declval(); +template <typename> class decay { +public: + typedef int type; +}; +template <typename...> struct common_type; +struct A { + template <typename, typename _Up> + static __success_type<typename decay<decltype(declval<_Up>)>::type> _S_test; +}; +template <typename _Tp, typename _Up> struct __common_type_impl : A { + typedef decltype(_S_test<_Tp, _Up>) type; +}; +template <typename _Tp, typename _Up> +struct common_type<_Tp, _Up> : __common_type_impl<_Tp, _Up> {}; +} +template <typename> struct B { struct _; }; +template <typename T> typename B<T>::_ type; +template <template <typename...> class> struct C; +template <template <typename...> class f> C<f> metafunction; +template <typename T> struct B<T>::_ {}; +namespace detail { +template <typename> struct _decltype; +} +template <template <typename...> class F> struct C { + template <typename... T> + auto operator()(T...) + -> decltype(type<typename F<detail::_decltype<T>...>::type>); +}; +auto common_type = metafunction<std::common_type>(0, 0); |