Commit e1bbb0bc by Alexandre Oliva Committed by Alexandre Oliva

[PR87770] test partial specializations for type dependence

When instantiating a partial specialization of a template member
function for a full specialization of a class template, we test
whether the context of variables local to the partial specialization,
i.e., the partial specialization itself, is dependent, and this ICEs
in type_dependent_expression_p, when checking that the function type
isn't type-dependent because it is not in a type-dependent scope.

We shouldn't have got that far: the previous block in
type_dependent_expression_p catches cases in which the function itself
takes template arguments of its own, but it only did so for primary
templates, not for partial specializations.  This patch fixes that.


for  gcc/cp/ChangeLog

	PR c++/87770
	* pt.c (instantiates_primary_template_p): New.
	(type_dependent_expression_p): Use it.

for  gcc/testsuite/ChangeLog

	PR c++/87770
	* g++.dg/pr87770.C: New.

From-SVN: r268529
parent ca0107a7
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> 2019-02-01 Jason Merrill <jason@redhat.com>
PR c++/88761 - ICE with reference capture of constant. PR c++/88761 - ICE with reference capture of constant.
......
...@@ -400,6 +400,36 @@ template_class_depth (tree type) ...@@ -400,6 +400,36 @@ template_class_depth (tree type)
return depth; 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. /* Subroutine of maybe_begin_member_template_processing.
Returns true if processing DECL needs us to push template parms. */ Returns true if processing DECL needs us to push template parms. */
...@@ -25683,7 +25713,7 @@ type_dependent_expression_p (tree expression) ...@@ -25683,7 +25713,7 @@ type_dependent_expression_p (tree expression)
that come from the template-id; the template arguments for the that come from the template-id; the template arguments for the
enclosing class do not make it type-dependent unless they are used in enclosing class do not make it type-dependent unless they are used in
the type of the decl. */ the type of the decl. */
if (PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (expression)) if (instantiates_primary_template_p (expression)
&& (any_dependent_template_arguments_p && (any_dependent_template_arguments_p
(INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression))))) (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
return true; return true;
......
2019-02-05 Alexandre Oliva <aoliva@redhat.com>
PR c++/87770
* g++.dg/pr87770.C: New.
2019-02-04 Harald Anlauf <anlauf@gmx.de> 2019-02-04 Harald Anlauf <anlauf@gmx.de>
PR fortran/89077 PR fortran/89077
......
// { 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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment