This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/67130 and 67131 (variable template-id issues)


These were introduced by my patch yesterday that keeps TEMPLATE_ID_EXPRs around longer for variable templates, so more places need to deal with them.

Tested x86_64-pc-linux-gnu, applying to trunk and 5.
commit 8814d2ca8d702ddca8c3e315f08275dbe3271cd6
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Aug 6 09:13:23 2015 -0400

    	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.

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);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]