diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6c474fdda16..65a850fc53c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-02-05 Alexandre Oliva + + PR c++/87770 + * pt.c (instantiates_primary_template_p): New. + (type_dependent_expression_p): Use it. + 2019-02-01 Jason Merrill PR c++/88761 - ICE with reference capture of constant. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9aa3c75d2d7..b8fbf4046f0 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -400,6 +400,36 @@ template_class_depth (tree type) 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. */ @@ -25683,7 +25713,7 @@ type_dependent_expression_p (tree expression) 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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 14db6287ff5..8a77c005c3b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-02-05 Alexandre Oliva + + PR c++/87770 + * g++.dg/pr87770.C: New. + 2019-02-04 Harald Anlauf PR fortran/89077 diff --git a/gcc/testsuite/g++.dg/pr87770.C b/gcc/testsuite/g++.dg/pr87770.C new file mode 100644 index 00000000000..69eff4a786f --- /dev/null +++ b/gcc/testsuite/g++.dg/pr87770.C @@ -0,0 +1,11 @@ +// { dg-do compile } + +template struct d { + template d(e); +}; +template <> template d::d(e); +template <> template d::d(e) { + long g; + (void)g; +} +template d::d(char);