The problem here was that when we instantiate G::bar, we want to instantiate F, and end up improperly pushing the declaration inside G, which leads to the ICE. Adjusting the call to pushclass is enough to fix this, which is what I propose doing for the 4.7 branch. For 4.8 I'm going to do more.

Richard: I think we need to resolve 53599 for 4.7.1, either by reverting the fix for 53137 or applying this patch. Do you have a preference?
commit ec323a89482ecd0b31124aeb3d486da48b0a4602
Author: Jason Merrill <ja...@redhat.com>
Date:   Thu Jun 7 15:16:05 2012 -0400

    	PR c++/53599
    	* pt.c (lookup_template_class_1): Use ts_global.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a2d8374..7f5682d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7564,7 +7564,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
 
 	  /* A local class.  Make sure the decl gets registered properly.  */
 	  if (context == current_function_decl)
-	    pushtag (DECL_NAME (gen_tmpl), t, /*tag_scope=*/ts_current);
+	    pushtag (DECL_NAME (gen_tmpl), t, /*tag_scope=*/ts_global);
 
 	  if (comp_template_args (CLASSTYPE_TI_ARGS (template_type), arglist))
 	    /* This instantiation is another name for the primary
diff --git a/gcc/testsuite/g++.dg/template/local7.C b/gcc/testsuite/g++.dg/template/local7.C
new file mode 100644
index 0000000..3045534
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/local7.C
@@ -0,0 +1,15 @@
+// PR c++/53599
+
+template <typename T>
+int foo ()
+{
+  struct F;
+  struct G
+  {
+    static int F::* bar();
+  };
+
+  return sizeof(G);
+}
+
+int z = foo <int> ();

Reply via email to