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.
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
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. */
--- /dev/null
+// 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>; }