+2019-02-05 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/87770
+ * pt.c (instantiates_primary_template_p): New.
+ (type_dependent_expression_p): Use it.
+
2019-02-01 Jason Merrill <jason@redhat.com>
PR c++/88761 - ICE with reference capture of constant.
return depth;
}
+/* Return TRUE if NODE instantiates a template that has arguments of
+ its own, be it directly a primary template or indirectly through a
+ partial specializations. */
+static bool
+instantiates_primary_template_p (tree node)
+{
+ tree tinfo = get_template_info (node);
+ if (!tinfo)
+ return false;
+
+ tree tmpl = TI_TEMPLATE (tinfo);
+ if (PRIMARY_TEMPLATE_P (tmpl))
+ return true;
+
+ if (!DECL_TEMPLATE_SPECIALIZATION (tmpl))
+ return false;
+
+ /* So now we know we have a specialization, but it could be a full
+ or a partial specialization. To tell which, compare the depth of
+ its template arguments with those of its context. */
+
+ tree ctxt = DECL_CONTEXT (tmpl);
+ tree ctinfo = get_template_info (ctxt);
+ if (!ctinfo)
+ return true;
+
+ return (TMPL_ARGS_DEPTH (TI_ARGS (tinfo))
+ > TMPL_ARGS_DEPTH (TI_ARGS (ctinfo)));
+}
+
/* Subroutine of maybe_begin_member_template_processing.
Returns true if processing DECL needs us to push template parms. */
that come from the template-id; the template arguments for the
enclosing class do not make it type-dependent unless they are used in
the type of the decl. */
- if (PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (expression))
+ if (instantiates_primary_template_p (expression)
&& (any_dependent_template_arguments_p
(INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
return true;
--- /dev/null
+// { dg-do compile }
+
+template <typename> struct d {
+ template <typename e> d(e);
+};
+template <> template <typename e> d<int>::d(e);
+template <> template <typename e> d<int>::d(e) {
+ long g;
+ (void)g;
+}
+template d<int>::d(char);