Patchwork C++ PATCH for c++/54511 (anonymous union in template function)

login
register
mail settings
Submitter Jason Merrill
Date Sept. 13, 2012, 2:53 p.m.
Message ID <5051F371.2090908@redhat.com>
Download mbox | patch
Permalink /patch/183639/
State New
Headers show

Comments

Jason Merrill - Sept. 13, 2012, 2:53 p.m.
Instantiating an anonymous union was problematic because we don't set up 
a mapping between the fake variables that point to the different 
members.  This patch fixes that by doing name lookup to find the 
corresponding fake variable in the instantiation, and then adding it to 
the hash table for later references.

Tested x86_64-pc-linux-gnu, applying to trunk, 4.7 and 4.6.

Patch

commit e1df1acb3674c52ee582ba8a5f756066e23e5016
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Sep 11 22:05:10 2012 -0400

    	PR c++/54511
    	* pt.c (tsubst_decl) [VAR_DECL]: Handle DECL_ANON_UNION_VAR_P.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 4cf2ed8..5b7976a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10443,6 +10443,16 @@  tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 	    break;
 	  }
 
+	if (TREE_CODE (t) == VAR_DECL && DECL_ANON_UNION_VAR_P (t))
+	  {
+	    /* Just use name lookup to find a member alias for an anonymous
+	       union, but then add it to the hash table.  */
+	    r = lookup_name (DECL_NAME (t));
+	    gcc_assert (DECL_ANON_UNION_VAR_P (r));
+	    register_local_specialization (r, t);
+	    break;
+	  }
+
 	/* Create a new node for the specialization we need.  */
 	r = copy_decl (t);
 	if (type == NULL_TREE)
diff --git a/gcc/testsuite/g++.dg/template/anonunion2.C b/gcc/testsuite/g++.dg/template/anonunion2.C
new file mode 100644
index 0000000..cb3c12d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/anonunion2.C
@@ -0,0 +1,6 @@ 
+template <int i>
+struct S
+{
+  S () { union { int a; }; a = 0; }
+};
+S<0> s;