OSDN Git Service

PR c++/36633
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 31 Jul 2008 17:38:08 +0000 (17:38 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 31 Jul 2008 17:38:08 +0000 (17:38 +0000)
        * init.c (build_new_1): Don't convert pointer to the data type
        until we're actually going to treat it as that type.

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

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

index f01593d..db536e4 100644 (file)
@@ -1,5 +1,9 @@
 2008-07-31  Jason Merrill  <jason@redhat.com>
 
+       PR c++/36633
+       * init.c (build_new_1): Don't convert pointer to the data type
+       until we're actually going to treat it as that type.
+
        PR c++/11309
        * tree.c (build_aggr_init_expr): Split out...
        (build_cplus_new): ...from here.
index 5535033..c6d63b8 100644 (file)
@@ -2055,11 +2055,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
       return rval;
     }
 
-  /* While we're working, use a pointer to the type we've actually
-     allocated. Store the result of the call in a variable so that we
-     can use it more than once.  */
-  full_pointer_type = build_pointer_type (full_type);
-  alloc_expr = get_target_expr (build_nop (full_pointer_type, alloc_call));
+  /* Store the result of the allocation call in a variable so that we can
+     use it more than once.  */
+  alloc_expr = get_target_expr (alloc_call);
   alloc_node = TARGET_EXPR_SLOT (alloc_expr);
 
   /* Strip any COMPOUND_EXPRs from ALLOC_CALL.  */
@@ -2111,16 +2109,17 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
       tree size_ptr_type;
 
       /* Adjust so we're pointing to the start of the object.  */
-      data_addr = get_target_expr (build2 (POINTER_PLUS_EXPR, full_pointer_type,
-                                          alloc_node, cookie_size));
+      data_addr = build2 (POINTER_PLUS_EXPR, TREE_TYPE (alloc_node),
+                         alloc_node, cookie_size);
 
       /* Store the number of bytes allocated so that we can know how
         many elements to destroy later.  We use the last sizeof
         (size_t) bytes to store the number of elements.  */
-      cookie_ptr = fold_build1 (NEGATE_EXPR, sizetype, size_in_bytes (sizetype));
+      cookie_ptr = size_binop (MINUS_EXPR, cookie_size, size_in_bytes (sizetype));
+      cookie_ptr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (alloc_node),
+                               alloc_node, cookie_ptr);
       size_ptr_type = build_pointer_type (sizetype);
-      cookie_ptr = build2 (POINTER_PLUS_EXPR, size_ptr_type,
-                          fold_convert (size_ptr_type, data_addr), cookie_ptr);
+      cookie_ptr = fold_convert (size_ptr_type, cookie_ptr);
       cookie = cp_build_indirect_ref (cookie_ptr, NULL, complain);
 
       cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
@@ -2134,11 +2133,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
 
          cookie = cp_build_indirect_ref (cookie_ptr, NULL, complain);
          cookie = build2 (MODIFY_EXPR, sizetype, cookie,
-                          size_in_bytes(elt_type));
+                          size_in_bytes (elt_type));
          cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
                                cookie, cookie_expr);
        }
-      data_addr = TARGET_EXPR_SLOT (data_addr);
     }
   else
     {
@@ -2146,6 +2144,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
       data_addr = alloc_node;
     }
 
+  /* Now use a pointer to the type we've actually allocated.  */
+  full_pointer_type = build_pointer_type (full_type);
+  data_addr = fold_convert (full_pointer_type, data_addr);
+
   /* Now initialize the allocated object.  Note that we preevaluate the
      initialization expression, apart from the actual constructor call or
      assignment--we do this because we want to delay the allocation as long
@@ -2241,11 +2243,13 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
          /* The Standard is unclear here, but the right thing to do
             is to use the same method for finding deallocation
             functions that we use for finding allocation functions.  */
-         cleanup = build_op_delete_call (dcode, alloc_node, size,
-                                         globally_qualified_p,
-                                         (placement_allocation_fn_p
-                                          ? alloc_call : NULL_TREE),
-                                         alloc_fn);
+         cleanup = (build_op_delete_call
+                    (dcode,
+                     fold_convert (full_pointer_type, alloc_node),
+                     size,
+                     globally_qualified_p,
+                     placement_allocation_fn_p ? alloc_call : NULL_TREE,
+                     alloc_fn));
 
          if (!cleanup)
            /* We're done.  */;
@@ -2300,7 +2304,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
   if (cookie_expr)
     rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), cookie_expr, rval);
 
-  if (rval == alloc_node)
+  if (rval == data_addr)
     /* If we don't have an initializer or a cookie, strip the TARGET_EXPR
        and return the call (which doesn't need to be adjusted).  */
     rval = TARGET_EXPR_INITIAL (alloc_expr);
diff --git a/gcc/testsuite/g++.dg/tree-ssa/new1.C b/gcc/testsuite/g++.dg/tree-ssa/new1.C
new file mode 100644 (file)
index 0000000..a859f0a
--- /dev/null
@@ -0,0 +1,42 @@
+// PR c++/36633
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall -fdump-tree-forwprop1" } */
+// No particular reason for choosing forwprop1 dump to look at.
+
+struct B { ~B() {} };
+struct D : public B {};
+//struct D {};
+
+struct my_deleter
+{
+  void operator()(D * d)
+  {
+    //    delete [] d;
+  }
+};
+
+struct smart_ptr
+{
+  smart_ptr(D * ptr) : p(ptr) { }
+  ~smart_ptr() { d(p); }
+  D * p;
+  my_deleter d;  
+};
+
+int
+test01()
+{
+  smart_ptr p(new D[7]);
+
+  return 0;
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "= .* \\+ -" "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */