aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-02-12 17:25:47 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2008-02-12 17:25:47 +0100
commita9de800a1d61a06926b273e73a596474242347e6 (patch)
tree87d8c554fcf5359f810fbbee23dc77a8d2956de6 /gcc
parent02e52ae514072eb565ae9d7451ee00756c4f5121 (diff)
downloadgcc-a9de800a1d61a06926b273e73a596474242347e6.zip
gcc-a9de800a1d61a06926b273e73a596474242347e6.tar.gz
gcc-a9de800a1d61a06926b273e73a596474242347e6.tar.bz2
re PR c++/34862 (operator new placement variant with reference arg not accepted by g++ 4.3)
PR c++/34862 * init.c (build_new_1): Don't create placement_expr before constructing alloc_call. Verify that the pointer is passed by value to operator new. * g++.dg/init/new27.C: New test. From-SVN: r132257
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/init.c37
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/init/new27.C40
4 files changed, 75 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c11dcd5..943eef3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2008-02-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34862
+ * init.c (build_new_1): Don't create placement_expr before
+ constructing alloc_call. Verify that the pointer is passed by
+ value to operator new.
+
2008-02-11 Jason Merrill <jason@redhat.com>
PR c++/35097
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index ec59207..040b335 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1800,7 +1800,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
beginning of the storage allocated for an array-new expression in
order to store the number of elements. */
tree cookie_size = NULL_TREE;
- tree placement_expr;
+ tree placement_expr = NULL_TREE;
/* True if the function we are calling is a placement allocation
function. */
bool placement_allocation_fn_p;
@@ -1892,19 +1892,6 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
alloc_fn = NULL_TREE;
- /* If PLACEMENT is a simple pointer type, then copy it into
- PLACEMENT_EXPR. */
- if (processing_template_decl
- || placement == NULL_TREE
- || TREE_CHAIN (placement) != NULL_TREE
- || TREE_CODE (TREE_TYPE (TREE_VALUE (placement))) != POINTER_TYPE)
- placement_expr = NULL_TREE;
- else
- {
- placement_expr = get_target_expr (TREE_VALUE (placement));
- placement = tree_cons (NULL_TREE, placement_expr, NULL_TREE);
- }
-
/* Allocate the object. */
if (! placement && TYPE_FOR_JAVA (elt_type))
{
@@ -1999,6 +1986,28 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
gcc_assert (alloc_fn != NULL_TREE);
+ /* If PLACEMENT is a simple pointer type and is not passed by reference,
+ then copy it into PLACEMENT_EXPR. */
+ if (!processing_template_decl
+ && placement != NULL_TREE
+ && TREE_CHAIN (placement) == NULL_TREE
+ && TREE_CODE (TREE_TYPE (TREE_VALUE (placement))) == POINTER_TYPE
+ && TREE_CODE (alloc_call) == CALL_EXPR
+ && call_expr_nargs (alloc_call) == 2
+ && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 0))) == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 1))) == POINTER_TYPE)
+ {
+ tree placement_arg = CALL_EXPR_ARG (alloc_call, 1);
+
+ if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg)))
+ || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg))))
+ {
+ placement_expr = get_target_expr (TREE_VALUE (placement));
+ CALL_EXPR_ARG (alloc_call, 1)
+ = convert (TREE_TYPE (placement_arg), placement_expr);
+ }
+ }
+
/* In the simple case, we can stop now. */
pointer_type = build_pointer_type (type);
if (!cookie_size && !is_initialized)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4ac1835..091bb28 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-02-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34862
+ * g++.dg/init/new27.C: New test.
+
2008-02-11 Paolo Carlini <pcarlini@suse.de>
PR c++/35077
diff --git a/gcc/testsuite/g++.dg/init/new27.C b/gcc/testsuite/g++.dg/init/new27.C
new file mode 100644
index 0000000..a6271c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/new27.C
@@ -0,0 +1,40 @@
+// PR c++/34862
+// { dg-do run }
+// { dg-options "-O2" }
+
+typedef __SIZE_TYPE__ size_t;
+extern "C" void abort ();
+
+struct T
+{
+ void *operator new (size_t, char *&);
+ T () { i[0] = 1; i[1] = 2; }
+ int i[2];
+};
+
+void *
+T::operator new (size_t size, char *&p)
+{
+ void *o = (void *) p;
+ p += size;
+ return o;
+}
+
+T *
+f (char *&x)
+{
+ return new (x) T ();
+}
+
+char buf[10 * sizeof (T)] __attribute__((aligned (__alignof (T))));
+
+int
+main ()
+{
+ char *p = buf;
+ T *t = f (p);
+ if (p != buf + sizeof (T))
+ abort ();
+ if (t->i[0] != 1 || t->i[1] != 2)
+ abort ();
+}