From d4600b3e3919b9977d70003251cd9ad1650c8307 Mon Sep 17 00:00:00 2001 From: jakub Date: Tue, 12 Feb 2008 16:25:47 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132257 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/init.c | 37 ++++++++++++++++++++++-------------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/init/new27.C | 40 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/init/new27.C 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 + + 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 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 + + PR c++/34862 + * g++.dg/init/new27.C: New test. + 2008-02-11 Paolo Carlini 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 (); +} -- 2.7.4