re PR c++/69009 (ICE in instantiate_decl, at cp/pt.c:21511)
authorJason Merrill <jason@redhat.com>
Sun, 31 Jan 2016 11:53:04 +0000 (06:53 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 31 Jan 2016 11:53:04 +0000 (06:53 -0500)
PR c++/69009

* pt.c (partial_specialization_p, impartial_args): New.
(instantiate_decl): Call impartial_args.

From-SVN: r233019

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

index 0113e5da6ce7e199818856a8ae53cd0ab035f79f..783fe72ff53d56d5ddf0702b4228fa95c7dbc047 100644 (file)
@@ -1,5 +1,9 @@
 2016-01-31  Jason Merrill  <jason@redhat.com>
 
+       PR c++/69009
+       * pt.c (partial_specialization_p, impartial_args): New.
+       (instantiate_decl): Call impartial_args.
+
        * mangle.c (maybe_check_abi_tags): New.
        (write_guarded_var_name): Call it.
        (mangle_ref_init_variable): Call check_abi_tags.
index 0d0e66497b13399cf934304cb451a8b056998aa4..27dfdf863c3aad6b90e1f7fb5e05db4b684785d7 100644 (file)
@@ -20746,6 +20746,36 @@ most_general_template (tree decl)
   return decl;
 }
 
+/* True iff the TEMPLATE_DECL tmpl is a partial specialization.  */
+
+static bool
+partial_specialization_p (tree tmpl)
+{
+  /* Any specialization has DECL_TEMPLATE_SPECIALIZATION.  */
+  if (!DECL_TEMPLATE_SPECIALIZATION (tmpl))
+    return false;
+  tree t = DECL_TI_TEMPLATE (tmpl);
+  /* A specialization that fully specializes one of the containing classes is
+     not a partial specialization.  */
+  return (list_length (DECL_TEMPLATE_PARMS (tmpl))
+         == list_length (DECL_TEMPLATE_PARMS (t)));
+}
+
+/* If TMPL is a partial specialization, return the arguments for its primary
+   template.  */
+
+static tree
+impartial_args (tree tmpl, tree args)
+{
+  if (!partial_specialization_p (tmpl))
+    return args;
+
+  /* If TMPL is a partial specialization, we need to substitute to get
+     the args for the primary template.  */
+  return tsubst_template_args (DECL_TI_ARGS (tmpl), args,
+                              tf_warning_or_error, tmpl);
+}
+
 /* Return the most specialized of the template partial specializations
    which can produce TARGET, a specialization of some class or variable
    template.  The value returned is actually a TREE_LIST; the TREE_VALUE is
@@ -21570,7 +21600,7 @@ instantiate_decl (tree d, int defer_ok,
     return d;
 
   gen_tmpl = most_general_template (tmpl);
-  gen_args = DECL_TI_ARGS (d);
+  gen_args = impartial_args (tmpl, DECL_TI_ARGS (d));
 
   if (tmpl != gen_tmpl)
     /* We should already have the extra args.  */
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ47.C b/gcc/testsuite/g++.dg/cpp1y/var-templ47.C
new file mode 100644 (file)
index 0000000..a40ec57
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/69009
+// { dg-do compile { target c++14 } }
+
+using _uchar = char;
+using _size_t = decltype(sizeof(_uchar));
+using size_t = _size_t;
+template <class T, T> struct integral_constant;
+template <bool b> using bool_constant = integral_constant<bool, b>;
+template <class> constexpr auto tuple_size_v = 0;
+template <class T> auto const tuple_size_v<T const volatile> = tuple_size_v<T>;
+template <class T>
+using tuple_size = integral_constant<size_t, tuple_size_v<T>>;
+template <typename Base, typename Deriv>
+using is_base_of = bool_constant<__is_base_of(Base, Deriv)>;
+template <class T, size_t N> void test() {
+  is_base_of<integral_constant<size_t, N>, tuple_size<T>> value(
+      is_base_of<integral_constant<size_t, N>, tuple_size<const volatile T>>);
+}
+void foo() { test<int, 0>; }