re PR c++/67130 (ICE: tree check: expected identifier_node, have template_decl in...
authorJason Merrill <jason@redhat.com>
Thu, 6 Aug 2015 14:26:18 +0000 (10:26 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 6 Aug 2015 14:26:18 +0000 (10:26 -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.

From-SVN: r226676

gcc/cp/ChangeLog
gcc/cp/mangle.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1y/var-templ42.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/var-templ43.C [new file with mode: 0644]

index 986b942f40088e84af5ea209d634826e3f74ed18..e8d45dc7ce6cd155e315e72049301673abcacbb3 100644 (file)
@@ -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
index d471f4f0a0681945eca64ce3e4af0de49d997f45..4518f20cc8eed8ff95c5a4ee899dfe5a6a75656e 100644 (file)
@@ -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);
index 08fb2ffb431f3f6d13b8d6e088c1c9a701888309..c3bafd3d37ccda358ce21222663eb4d83b59e206 100644 (file)
@@ -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 (file)
index 0000000..a43149d
--- /dev/null
@@ -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 (file)
index 0000000..414802f
--- /dev/null
@@ -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);