...because apparently someone wants to write such a thing?

Anyway, it's a simple matter of looking through templates when calling reset_decl_linkage.

Tested x86_64-pc-linux-gnu, applying to trunk and 5.
commit c96622dda7826a32ccc3caa34d727d8c1e7c3b3f
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Feb 17 16:01:48 2016 -0500

    	PR c++/68679
    	* decl2.c (reset_type_linkage_2): Look through member templates.

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 15d7617..73b0d28 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2685,14 +2685,22 @@ reset_type_linkage_2 (tree type)
 	  reset_decl_linkage (ti);
 	}
       for (tree m = TYPE_FIELDS (type); m; m = DECL_CHAIN (m))
-	if (VAR_P (m))
-	  reset_decl_linkage (m);
+	{
+	  tree mem = STRIP_TEMPLATE (m);
+	  if (VAR_P (mem))
+	    reset_decl_linkage (mem);
+	}
       for (tree m = TYPE_METHODS (type); m; m = DECL_CHAIN (m))
 	{
-	  reset_decl_linkage (m);
-	  if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (m))
-	    /* Also update its name, for cxx_dwarf_name.  */
-	    DECL_NAME (m) = TYPE_IDENTIFIER (type);
+	  tree mem = STRIP_TEMPLATE (m);
+	  reset_decl_linkage (mem);
+	  if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (mem))
+	    {
+	      /* Also update its name, for cxx_dwarf_name.  */
+	      DECL_NAME (mem) = TYPE_IDENTIFIER (type);
+	      if (m != mem)
+		DECL_NAME (m) = TYPE_IDENTIFIER (type);
+	    }
 	}
       binding_table_foreach (CLASSTYPE_NESTED_UTDS (type),
 			     bt_reset_linkage_2, NULL);
diff --git a/gcc/testsuite/g++.dg/other/anon8.C b/gcc/testsuite/g++.dg/other/anon8.C
new file mode 100644
index 0000000..1fdd4c1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/anon8.C
@@ -0,0 +1,9 @@
+// PR c++/68679
+
+typedef struct {
+  struct {
+    unsigned d[4];
+    template<typename T>
+    unsigned operator[] (T i) const { return d[i]; }
+  } c;
+} A;

Reply via email to