]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR87770] test partial specializations for type dependence
authorAlexandre Oliva <aoliva@redhat.com>
Tue, 5 Feb 2019 06:11:25 +0000 (06:11 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Tue, 5 Feb 2019 06:11:25 +0000 (06:11 +0000)
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

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

index 6c474fdda16c15059eaa3ae871a7e2fe996ce7cc..65a850fc53c8d5abeb66b60ad7388877d2f2e382 100644 (file)
@@ -1,3 +1,9 @@
+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.
index 9aa3c75d2d74a5860445c2c6cb7a6aba2cdf5e9d..b8fbf4046f0790c0262fec99ddf0c2d2cd411f43 100644 (file)
@@ -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;
index 14db6287ff5e4ade766f6f2bccf9d14724a7a29f..8a77c005c3bf391b5163491078a1472d814ee642 100644 (file)
@@ -1,3 +1,8 @@
+2019-02-05  Alexandre Oliva <aoliva@redhat.com>
+
+       PR c++/87770
+       * g++.dg/pr87770.C: New.
+
 2019-02-04  Harald Anlauf  <anlauf@gmx.de>
 
        PR fortran/89077
diff --git a/gcc/testsuite/g++.dg/pr87770.C b/gcc/testsuite/g++.dg/pr87770.C
new file mode 100644 (file)
index 0000000..69eff4a
--- /dev/null
@@ -0,0 +1,11 @@
+// { 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);