[gcc r8-10066] c++: test partial specializations for type dependence [PR87770]

Jason Merrill jason@gcc.gnu.org
Tue Feb 25 21:42:00 GMT 2020


https://gcc.gnu.org/g:d2221c1179354ad71c4944ea0cc634803aae98f1

commit r8-10066-gd2221c1179354ad71c4944ea0cc634803aae98f1
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Tue Feb 5 06:11:25 2019 +0000

    c++: test partial specializations for type dependence [PR87770]
    
    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.
    
    gcc/cp/ChangeLog
    2019-02-05  Alexandre Oliva <aoliva@redhat.com>
    
    	PR c++/87770
    	* pt.c (instantiates_primary_template_p): New.
    	(type_dependent_expression_p): Use it.
    
    gcc/testsuite/ChangeLog
    2019-02-05  Alexandre Oliva <aoliva@redhat.com>
    
    	PR c++/87770
    	* g++.dg/pr87770.C: New.

Diff:
---
 gcc/cp/ChangeLog               |  6 ++++++
 gcc/cp/pt.c                    | 32 +++++++++++++++++++++++++++++++-
 gcc/testsuite/ChangeLog        |  5 +++++
 gcc/testsuite/g++.dg/pr87770.C | 11 +++++++++++
 4 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b73cc56..a6b54d5 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
+
 2020-02-25  Marek Polacek  <polacek@redhat.com>
 
 	PR c++/92745 - bogus error when initializing array of vectors.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2dc5af4..42634af 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -398,6 +398,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.  */
 
@@ -25166,7 +25196,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 5e54185..ace9be5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-02-05  Alexandre Oliva <aoliva@redhat.com>
+
+	PR c++/87770
+	* g++.dg/pr87770.C: New.
+
 2020-02-25  Marek Polacek  <polacek@redhat.com>
 	    Jakub Jelinek  <jakub@redhat.com>
 
diff --git a/gcc/testsuite/g++.dg/pr87770.C b/gcc/testsuite/g++.dg/pr87770.C
new file mode 100644
index 0000000..69eff4a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr87770.C
@@ -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);



More information about the Gcc-cvs mailing list