aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/init.c25
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/other/new1.C20
4 files changed, 42 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6f31ebd..e82644c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2002-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/4884.
+ * init.c (build_new_1): Allow for the fact the result of
+ build_function_call may be a COMPOUND_EXPR.
+
2002-03-26 Nathan Sidwell <nathan@codesourcery.com>
PR c++/5682
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index a1d6578..de3fd2c39 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -2189,6 +2189,7 @@ build_new_1 (exp)
tree full_type;
tree nelts = NULL_TREE;
tree alloc_call, alloc_expr, alloc_node;
+ tree alloc_fn;
tree cookie_expr, init_expr;
int has_array = 0;
enum tree_code code;
@@ -2329,13 +2330,14 @@ build_new_1 (exp)
if (alloc_call == error_mark_node)
return error_mark_node;
- /* The ALLOC_CALL should be a CALL_EXPR, and the first operand
- should be the address of a known FUNCTION_DECL. */
- my_friendly_assert (TREE_CODE (alloc_call) == CALL_EXPR, 20000521);
- t = TREE_OPERAND (alloc_call, 0);
- my_friendly_assert (TREE_CODE (t) == ADDR_EXPR, 20000521);
- t = TREE_OPERAND (t, 0);
- my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL, 20000521);
+ /* The ALLOC_CALL should be a CALL_EXPR -- or a COMPOUND_EXPR whose
+ right-hand-side is ultimately a CALL_EXPR -- and the first
+ operand should be the address of a known FUNCTION_DECL. */
+ t = alloc_call;
+ while (TREE_CODE (t) == COMPOUND_EXPR)
+ t = TREE_OPERAND (t, 1);
+ alloc_fn = get_callee_fndecl (t);
+ my_friendly_assert (alloc_fn != NULL_TREE, 20020325);
/* Now, check to see if this function is actually a placement
allocation function. This can happen even when PLACEMENT is NULL
because we might have something like:
@@ -2347,7 +2349,8 @@ build_new_1 (exp)
one argument, or there are variable arguments, then this is a
placement allocation function. */
placement_allocation_fn_p
- = (type_num_arguments (TREE_TYPE (t)) > 1 || varargs_function_p (t));
+ = (type_num_arguments (TREE_TYPE (alloc_fn)) > 1
+ || varargs_function_p (alloc_fn));
/* unless an allocation function is declared with an empty excep-
tion-specification (_except.spec_), throw(), it indicates failure to
@@ -2359,11 +2362,7 @@ build_new_1 (exp)
So check for a null exception spec on the op new we just called. */
- /* The ADDR_EXPR. */
- t = TREE_OPERAND (alloc_call, 0);
- /* The function. */
- t = TREE_OPERAND (t, 0);
- nothrow = TYPE_NOTHROW_P (TREE_TYPE (t));
+ nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn));
check_new = (flag_check_new || nothrow) && ! use_java_new;
alloc_expr = alloc_call;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f78d27e..1862977 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2002-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ * g++.dg/init/new1.C: New test.
+
2002-03-26 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/abi/vbase9.C: New test.
diff --git a/gcc/testsuite/g++.dg/other/new1.C b/gcc/testsuite/g++.dg/other/new1.C
new file mode 100644
index 0000000..1acfa26
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/new1.C
@@ -0,0 +1,20 @@
+// Origin: asharji@uwaterloo.ca
+
+// { dg-do compile }
+// { dg-options "-fvolatile" }
+
+typedef unsigned int size_t;
+
+class bar {
+ int i;
+ public :
+ void * operator new ( size_t , void * storage );
+};
+
+class foo {
+ int storage[ 5 ];
+ public:
+ void mem ( ) {
+ bar *s = new ( ( void * ) & storage ) bar;
+ }
+};