pt.c (tsubst_decl): Call coerce_innermost_template_parms.
authorJason Merrill <jason@redhat.com>
Mon, 18 May 2015 18:08:48 +0000 (14:08 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 18 May 2015 18:08:48 +0000 (14:08 -0400)
* pt.c (tsubst_decl) [VAR_DECL]: Call coerce_innermost_template_parms.
(determine_specialization): Call coerce_template_parms.

From-SVN: r223304

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

index 957dc1deed50392f39598ae92b8839c6e6415320..04576e5a8a0b88d156f380e4f1ac4173ea18debe 100644 (file)
@@ -1,5 +1,8 @@
 2015-05-18  Jason Merrill  <jason@redhat.com>
 
+       * pt.c (tsubst_decl) [VAR_DECL]: Call coerce_innermost_template_parms.
+       (determine_specialization): Call coerce_template_parms.
+
        DR 1391
        * pt.c (type_unification_real): Check convertibility here.
        (unify_one_argument): Not here.
index 2cd36c9c9fff6e96f0a917b25d43e12ea3cb3a4b..2166f5fb65ea99a2585f6fa74cf2a64cfd6853c9 100644 (file)
@@ -1919,7 +1919,13 @@ determine_specialization (tree template_id,
     ++header_count;
 
   if (variable_template_p (fns))
-    templates = tree_cons (explicit_targs, fns, templates);
+    {
+      tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (fns));
+      targs = coerce_template_parms (parms, explicit_targs, fns,
+                                    tf_warning_or_error,
+                                    /*req_all*/true, /*use_defarg*/true);
+      templates = tree_cons (targs, fns, templates);
+    }
   else for (; fns; fns = OVL_NEXT (fns))
     {
       tree fn = OVL_CURRENT (fns);
@@ -11265,6 +11271,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                tmpl = DECL_TI_TEMPLATE (t);
                gen_tmpl = most_general_template (tmpl);
                argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
+               if (argvec != error_mark_node)
+                 argvec = (coerce_innermost_template_parms
+                           (DECL_TEMPLATE_PARMS (gen_tmpl),
+                            argvec, t, complain,
+                            /*all*/true, /*defarg*/true));
                if (argvec == error_mark_node)
                  RETURN (error_mark_node);
                hash = hash_tmpl_and_args (gen_tmpl, argvec);
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ25.C b/gcc/testsuite/g++.dg/cpp1y/var-templ25.C
new file mode 100644 (file)
index 0000000..8253eac
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-do compile { target c++14 } }
+
+using fl = float;
+
+template<class T> const int V = 0;
+template<> const int V<fl> = 42;
+
+static_assert(V<float> == 42, "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ26.C b/gcc/testsuite/g++.dg/cpp1y/var-templ26.C
new file mode 100644 (file)
index 0000000..9ac0777
--- /dev/null
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++14 } }
+
+template <class T> const int V = 0;
+template <> const int V<char> = 42;
+
+template <class T>
+struct A
+{
+  using N = T;
+};
+
+#define SA(X) static_assert((X),#X)
+template <class T>
+struct B
+{
+  SA(V<typename A<T>::N> == 42);
+};
+
+B<char> b;