aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@gcc.gnu.org>2015-07-15 00:01:21 +0000
committerPatrick Palka <ppalka@gcc.gnu.org>2015-07-15 00:01:21 +0000
commit09f725f4a6c0280681d375d0e204e4a6419dab53 (patch)
treee2551526421df58d3885fba451735651ba121582
parent524d2e49f2814e87875c1a5e911688027e8a3d91 (diff)
downloadgcc-09f725f4a6c0280681d375d0e204e4a6419dab53.zip
gcc-09f725f4a6c0280681d375d0e204e4a6419dab53.tar.gz
gcc-09f725f4a6c0280681d375d0e204e4a6419dab53.tar.bz2
re PR c++/66850 (Adding a forward declaration of a template containing a template template parm causes ICE on valid code)
Fix PR c++/66850 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. From-SVN: r225801
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/pt.c25
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/pr66850.C44
4 files changed, 80 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ec50f75..00cbe47 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 718befd..95ec376 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f961db7..b5a2707 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..31c1290
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr66850.C
@@ -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;
+ };
+ };
+}