]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix PR c++/66850
authorppalka <ppalka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 15 Jul 2015 00:01:21 +0000 (00:01 +0000)
committerppalka <ppalka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 15 Jul 2015 00:01:21 +0000 (00:01 +0000)
gcc/cp/ChangeLog:

PR c++/66850
* pt.c (redeclare_class_template): Set the DECL_CONTEXTs of each
template template parm in the redeclaration.
(lookup_template_class_1): Peel off irrelevant template levels
from current_template_parms before augmenting the argument
list.

gcc/testsuite/ChangeLog:

PR c++/66850
* g++.dg/template/pr66850.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225801 138bc75d-0d04-0410-961f-82ee72b054a4

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

index ec50f75558cdf0372f42b022c922ce09ed4677cf..00cbe47dfa42637e78a314116363128086cab26e 100644 (file)
@@ -1,3 +1,12 @@
+2015-07-14  Patrick Palka  <ppalka@gcc.gnu.org>
+
+       PR c++/66850
+       * pt.c (redeclare_class_template): Set the DECL_CONTEXTs of each
+       template template parm in the redeclaration.
+       (lookup_template_class_1): Peel off irrelevant template levels
+       from current_template_parms before augmenting the argument
+       list.
+
 2015-07-14  Andrea Azzarone  <azzaronea@gmail.com>
 
        PR c++/65071
index 718befd3f7b2a5542657ad941730fbddbd285939..95ec376430a41a6320ac97d0d78f4634a3b6e4a4 100644 (file)
@@ -5302,6 +5302,14 @@ redeclare_class_template (tree type, tree parms)
        /* Update the new parameters, too; they'll be used as the
           parameters for any members.  */
        TREE_PURPOSE (TREE_VEC_ELT (parms, i)) = tmpl_default;
+
+      /* Give each template template parm in this redeclaration a
+        DECL_CONTEXT of the template for which they are a parameter.  */
+      if (TREE_CODE (parm) == TEMPLATE_DECL)
+       {
+         gcc_assert (DECL_CONTEXT (parm) == NULL_TREE);
+         DECL_CONTEXT (parm) = tmpl;
+       }
     }
 
     return true;
@@ -7754,9 +7762,20 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
       if (outer)
        outer = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (outer)));
       else if (current_template_parms)
-       /* This is an argument of the current template, so we haven't set
-          DECL_CONTEXT yet.  */
-       outer = current_template_args ();
+       {
+         /* This is an argument of the current template, so we haven't set
+            DECL_CONTEXT yet.  */
+         tree relevant_template_parms;
+
+         /* Parameter levels that are greater than the level of the given
+            template template parm are irrelevant.  */
+         relevant_template_parms = current_template_parms;
+         while (TMPL_PARMS_DEPTH (relevant_template_parms)
+                != TEMPLATE_TYPE_LEVEL (TREE_TYPE (templ)))
+           relevant_template_parms = TREE_CHAIN (relevant_template_parms);
+
+         outer = template_parms_to_args (relevant_template_parms);
+       }
 
       if (outer)
        arglist = add_to_template_args (outer, arglist);
index f961db7c3ba3614c79bf0ecd808e004161a737a9..b5a27072e8e5c0b398cd82c8219aceba2d59ba82 100644 (file)
@@ -1,3 +1,8 @@
+2015-07-14  Patrick Palka  <ppalka@gcc.gnu.org>
+
+       PR c++/66850
+       * g++.dg/template/pr66850.C: New test.
+
 2015-07-14  Sandra Loosemore  <sandra@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
            Chung-Lin Tang  <cltang@codesourcery.com>
diff --git a/gcc/testsuite/g++.dg/template/pr66850.C b/gcc/testsuite/g++.dg/template/pr66850.C
new file mode 100644 (file)
index 0000000..31c1290
--- /dev/null
@@ -0,0 +1,44 @@
+// PR c++/66850
+// Each namespace contains an otherwise standalone test case, none of which
+// should cause an ICE.
+
+namespace X {
+  template <template <typename U, U> class> struct Sort;
+
+  template <template <typename U, U> class Comparator>
+  struct Sort
+  {
+    template <int I>
+    struct less_than
+    {
+      Comparator<int, I> a;
+    };
+  };
+}
+
+namespace Y {
+  template <typename C, C> struct integral_constant {};
+
+  template <typename T, template <typename U, U> class> struct Sort;
+
+  template <template <typename U, U> class Comparator>
+  struct Sort<int, Comparator>
+  {
+      template <int I> struct less_than:
+          integral_constant<bool, Comparator<int, I>::value> {};
+  };
+}
+
+namespace Z {
+  template <typename T, template <typename U, U> class> struct Sort;
+
+  template <template <typename U, U> class Comparator>
+  struct Sort<int, Comparator>
+  {
+    template <int I>
+    struct less_than
+    {
+      Comparator<int, I> a;
+    };
+  };
+}