This ICE was introduced when I adjusted lookup_and_check_tag to find
template template parameters so that they can be friends. But in this
case that meant we started to try to define the ttp as a class, leading
to chaos. In lookup_and_check_tag we can tell that we're in a class
definition by looking at the scope, and then ignore ttp in that specific
context.
Tested x86_64-pc-linux-gnu, applying to trunk and 4.8.
commit b071be05acf3f427a59be19e8ef327e4ff20106e
Author: Jason Merrill <ja...@redhat.com>
Date: Mon Jan 27 13:20:37 2014 -0500
PR c++/58632
* decl.c (lookup_and_check_tag): Ignore template parameters if
scope == ts_current.
* pt.c (check_template_shadow): Don't complain about the injected
class name.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index aca96fc..e14e401 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -11982,7 +11982,10 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
if (decl
&& (DECL_CLASS_TEMPLATE_P (decl)
- || DECL_TEMPLATE_TEMPLATE_PARM_P (decl)))
+ /* If scope is ts_current we're defining a class, so ignore a
+ template template parameter. */
+ || (scope != ts_current
+ && DECL_TEMPLATE_TEMPLATE_PARM_P (decl))))
decl = DECL_TEMPLATE_RESULT (decl);
if (decl && TREE_CODE (decl) == TYPE_DECL)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 47d07db..6c68bae 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3527,6 +3527,11 @@ check_template_shadow (tree decl)
&& TEMPLATE_PARMS_FOR_INLINE (current_template_parms)))
return true;
+ /* Don't complain about the injected class name, as we've already
+ complained about the class itself. */
+ if (DECL_SELF_REFERENCE_P (decl))
+ return false;
+
error ("declaration of %q+#D", decl);
error (" shadows template parm %q+#D", olddecl);
return false;
diff --git a/gcc/testsuite/g++.dg/template/shadow1.C b/gcc/testsuite/g++.dg/template/shadow1.C
new file mode 100644
index 0000000..6eb30d0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/shadow1.C
@@ -0,0 +1,4 @@
+// PR c++/58632
+
+template<template<int I> class A> // { dg-message "shadows" }
+class A {}; // { dg-error "declaration" }