diff options
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/init.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/ctor1.C | 57 |
4 files changed, 71 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8abfb73..cce0b8e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2002-10-12 Nathan Sidwell <nathan@codesourcery.com> + + * init.c (build_delete): Do not apply save_expr for arrays. + (build_vec_delete): Likewise. + 2002-10-14 Mark Mitchell <mark@codesourcery.com> * decl.c (layout_var_decl): Call layout_decl even for variables diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 0fefc12..3e71e9f 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3099,8 +3099,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) else if (TREE_CODE (type) == ARRAY_TYPE) { handle_array: - if (TREE_SIDE_EFFECTS (addr)) - addr = save_expr (addr); + if (TYPE_DOMAIN (type) == NULL_TREE) { error ("unknown array size in delete"); @@ -3342,15 +3341,13 @@ build_vec_delete (base, maxindex, auto_delete_vec, use_global_delete) base = stabilize_reference (base); - /* Since we can use base many times, save_expr it. */ - if (TREE_SIDE_EFFECTS (base)) - base = save_expr (base); - if (TREE_CODE (type) == POINTER_TYPE) { /* Step back one from start of vector, and read dimension. */ tree cookie_addr; + if (TREE_SIDE_EFFECTS (base)) + base = save_expr (base); type = strip_array_types (TREE_TYPE (type)); cookie_addr = build (MINUS_EXPR, build_pointer_type (sizetype), @@ -3364,6 +3361,8 @@ build_vec_delete (base, maxindex, auto_delete_vec, use_global_delete) maxindex = array_type_nelts_total (type); type = strip_array_types (type); base = build_unary_op (ADDR_EXPR, base, 1); + if (TREE_SIDE_EFFECTS (base)) + base = save_expr (base); } else { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 58a337c..5b77af5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-10-15 Nathan Sidwell <nathan@codesourcery.com> + + * g++.dg/init/ctor1.C: New test. + 2002-10-15 Ulrich Weigand <uweigand@de.ibm.com> * gcc.c-torture/execute/20021015-1.c: New test. diff --git a/gcc/testsuite/g++.dg/init/ctor1.C b/gcc/testsuite/g++.dg/init/ctor1.C new file mode 100644 index 0000000..aeb509b --- /dev/null +++ b/gcc/testsuite/g++.dg/init/ctor1.C @@ -0,0 +1,57 @@ +// { dg-do run } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 12 Oct 2002 <nathan@codesourcery.com> + +// From WindRiver SPR 80797 +// We were inadvertently SAVE_EXPRing volatile arrays during delete[] + +struct A +{ + A *ptr; + static int ok; + + A () {ptr = this;} + ~A () {ok = ptr == this;} +}; +int A::ok = -1; + +struct B +{ + B *ptr; + static int ok; + + B () {ptr = this;} + ~B () {ok = ptr == this;} +}; +int B::ok = -1; + +struct C +{ + A volatile a; + B volatile b[1]; + + C (); +}; + +C::C () +{ + throw 1; +} + +int main () +{ + try + { + C c; + } + catch (...) + { + if (A::ok != 1) + return 1; + if (B::ok != 1) + return 2; + return 0; + } + return 3; +} |