OSDN Git Service

PR c++/35116
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 9 Feb 2008 03:40:14 +0000 (03:40 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 9 Feb 2008 03:40:14 +0000 (03:40 +0000)
        * tree.c (build_target_expr_with_type): Handle void initializer.
        (bot_manip): Remap slot before recursing.

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

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/g++.dg/init/value2.C [new file with mode: 0644]

index 9fdd55b..da9668d 100644 (file)
@@ -1,3 +1,9 @@
+2008-02-08  Jason Merrill  <jason@redhat.com>
+
+       PR c++/35116
+       * tree.c (build_target_expr_with_type): Handle void initializer.
+       (bot_manip): Remap slot before recursing.
+
 2008-02-06  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        PR other/35107
index b14462f..e893442 100644 (file)
@@ -415,10 +415,12 @@ build_target_expr_with_type (tree init, tree type)
   if (TREE_CODE (init) == TARGET_EXPR)
     return init;
   else if (CLASS_TYPE_P (type) && !TYPE_HAS_TRIVIAL_INIT_REF (type)
+          && !VOID_TYPE_P (TREE_TYPE (init))
           && TREE_CODE (init) != COND_EXPR
           && TREE_CODE (init) != CONSTRUCTOR
           && TREE_CODE (init) != VA_ARG_EXPR)
-    /* We need to build up a copy constructor call.  COND_EXPR is a special
+    /* We need to build up a copy constructor call.  A void initializer
+       means we're being called from bot_manip.  COND_EXPR is a special
        case because we already have copies on the arms and we don't want
        another one here.  A CONSTRUCTOR is aggregate initialization, which
        is handled separately.  A VA_ARG_EXPR is magic creation of an
@@ -1468,17 +1470,17 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
       tree u;
 
       if (TREE_CODE (TREE_OPERAND (t, 1)) == AGGR_INIT_EXPR)
-       u = build_cplus_new
-         (TREE_TYPE (t), break_out_target_exprs (TREE_OPERAND (t, 1)));
+       u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1));
       else
-       u = build_target_expr_with_type
-         (break_out_target_exprs (TREE_OPERAND (t, 1)), TREE_TYPE (t));
+       u = build_target_expr_with_type (TREE_OPERAND (t, 1), TREE_TYPE (t));
 
       /* Map the old variable to the new one.  */
       splay_tree_insert (target_remap,
                         (splay_tree_key) TREE_OPERAND (t, 0),
                         (splay_tree_value) TREE_OPERAND (u, 0));
 
+      TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1));
+
       /* Replace the old expression with the new version.  */
       *tp = u;
       /* We don't have to go below this point; the recursive call to
diff --git a/gcc/testsuite/g++.dg/init/value2.C b/gcc/testsuite/g++.dg/init/value2.C
new file mode 100644 (file)
index 0000000..fbe1664
--- /dev/null
@@ -0,0 +1,23 @@
+// PR c++/35116
+// Test that break_out_target_exprs works properly with complex
+// value-initialization.
+
+struct A
+{
+  virtual void f ();
+};
+
+struct B
+{
+  A a;
+};
+
+struct C
+{
+  C (int, B = B());
+};
+
+void f ()
+{
+  C c (4);
+}