cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 30 May 2001 08:44:56 +0000 (08:44 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 30 May 2001 08:44:56 +0000 (08:44 +0000)
PR g++/2936
* decl.c (finish_anon_union): Copy context.
* optimize.c (remap_decl): Remap anonymous aggregate members too.
testsuite:
* g++.old-deja/g++.other/optimize3.C: New file.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@42705 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/optimize.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.other/optimize3.C [new file with mode: 0644]

index 2792f45..e78635c 100644 (file)
@@ -1,3 +1,9 @@
+2001-05-30  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR g++/2936
+       * decl.c (finish_anon_union): Copy context.
+       * optimize.c (remap_decl): Remap anonymous aggregate members too.
+
 2001-05-26  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR g++/2823
index f81d7e3..8676dd8 100644 (file)
@@ -106,8 +106,7 @@ static void update_cloned_parm PARAMS ((tree, tree));
    decisions about when a function is too big to inline.  */
 #define INSNS_PER_STMT (10)
 
-/* Remap DECL during the copying of the BLOCK tree for the function.
-   DATA is really an `inline_data *'.  */
+/* Remap DECL during the copying of the BLOCK tree for the function.  */
 
 static tree
 remap_decl (decl, id)
@@ -149,6 +148,26 @@ remap_decl (decl, id)
                     copy_body_r, id, NULL);
        }
 
+      if (!DECL_NAME (t) && TREE_TYPE (t)
+         && ANON_AGGR_TYPE_P (TREE_TYPE ((t))))
+       {
+         /* For a VAR_DECL of anonymous type, we must also copy the
+            member VAR_DECLS here and rechain the
+            DECL_ANON_UNION_ELEMS. */
+         tree members = NULL;
+         tree src;
+         
+         for (src = DECL_ANON_UNION_ELEMS (t); src;
+              src = TREE_CHAIN (src))
+           {
+             tree member = remap_decl (TREE_VALUE (src), id);
+
+             my_friendly_assert (!TREE_PURPOSE (src), 20010529);
+             members = tree_cons (NULL, member, members);
+           }
+         DECL_ANON_UNION_ELEMS (t) = nreverse (members);
+       }
+      
       /* Remember it, so that if we encounter this local entity
         again we can reuse this copy.  */
       n = splay_tree_insert (id->decl_map,
index 49d5a43..c5126b7 100644 (file)
@@ -1,3 +1,7 @@
+2001-05-30  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.old-deja/g++.other/optimize3.C: New file.
+
 2001-05-29  Jeffrey Oldham  <oldham@codesourcery.com>
 
         * gcc.c-torture/compile/20010518-2.x: New file to compile, not
diff --git a/gcc/testsuite/g++.old-deja/g++.other/optimize3.C b/gcc/testsuite/g++.old-deja/g++.other/optimize3.C
new file mode 100644 (file)
index 0000000..737aabb
--- /dev/null
@@ -0,0 +1,38 @@
+// Special g++ Options: -O2
+// 
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 29 May 2001 <nathan@codesourcery.com>
+
+// Bug 2936. We ICE'd on tree inlining a function with an anonymous
+// union decl.
+
+inline const unsigned char *Foo (const char *string)
+{
+  union
+  {
+    const char *p1;
+    const unsigned char *p2;
+  };
+  p1 = 0;
+  p2 = 0;
+
+
+  p1 = string;
+  return p2;
+  
+}
+
+const unsigned char *Baz (const char *string)
+{
+  return Foo (string);
+}
+
+int main ()
+{
+  const char *string = "s";
+  const unsigned char *result;
+
+  result = Baz (string);
+  return (static_cast <const void *> (result)
+         != static_cast <const void *> (string));
+}