diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2004-12-09 09:37:37 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2004-12-09 09:37:37 +0000 |
commit | 9476364759b1dc6e0f79b381b6adb7f995cc2706 (patch) | |
tree | c90b357b9524e70af672bd367baeefb8eeb3758d /gcc | |
parent | 42fabf21b2167ab9d0fc8482b297a7e75ff2964f (diff) | |
download | gcc-9476364759b1dc6e0f79b381b6adb7f995cc2706.zip gcc-9476364759b1dc6e0f79b381b6adb7f995cc2706.tar.gz gcc-9476364759b1dc6e0f79b381b6adb7f995cc2706.tar.bz2 |
re PR c++/16681 (array initialization in struct construct is a memory hog)
cp:
PR c++/16681
* init.c (build_zero_init): Build a RANGE_EXPR for an array
initializer.
testsuite:
PR c++/16681
* g++.dg/init/array15.C: New.
* g++.dg/init/array16.C: New.
From-SVN: r91928
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/init.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/array15.C | 46 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/array16.C | 106 |
5 files changed, 174 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d37b963..2d73639 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-12-09 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/16681 + * init.c (build_zero_init): Build a RANGE_EXPR for an array + initializer. + 2004-12-08 Kelley Cook <kcook@gcc.gnu.org> * typeck.c: Remove DOS line endings. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 95b57b2..70703ef 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -214,7 +214,6 @@ build_zero_init (tree type, tree nelts, bool static_storage_p) } else if (TREE_CODE (type) == ARRAY_TYPE) { - tree index; tree max_index; tree inits; @@ -228,14 +227,16 @@ build_zero_init (tree type, tree nelts, bool static_storage_p) /* A zero-sized array, which is accepted as an extension, will have an upper bound of -1. */ if (!tree_int_cst_equal (max_index, integer_minus_one_node)) - for (index = size_zero_node; - !tree_int_cst_lt (max_index, index); - index = size_binop (PLUS_EXPR, index, size_one_node)) - inits = tree_cons (index, - build_zero_init (TREE_TYPE (type), - /*nelts=*/NULL_TREE, - static_storage_p), - inits); + { + tree elt_init = build_zero_init (TREE_TYPE (type), + /*nelts=*/NULL_TREE, + static_storage_p); + tree range = build2 (RANGE_EXPR, + sizetype, size_zero_node, max_index); + + inits = tree_cons (range, elt_init, inits); + } + CONSTRUCTOR_ELTS (init) = nreverse (inits); } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f946bf1..d8ad0ad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2004-12-09 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/16681 + * g++.dg/init/array15.C: New. + * g++.dg/init/array16.C: New. + 2004-12-08 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de> PR fortran/18826 diff --git a/gcc/testsuite/g++.dg/init/array15.C b/gcc/testsuite/g++.dg/init/array15.C new file mode 100644 index 0000000..17160d0 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array15.C @@ -0,0 +1,46 @@ +// { dg-do run } + +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 8 Dec 2004 <nathan@codesourcery.com> + +// PR 16681 too much memory used +// Origin: Matt LaFary <lafary@activmedia.com> + +struct foo { + unsigned char buffer[4111222]; + foo() ; + bool check () const; +}; + +foo::foo () + : buffer() +{} + +bool foo::check () const +{ + for (unsigned ix = sizeof (buffer); ix--;) + if (buffer[ix]) + return false; + return true; +} + +void *operator new (__SIZE_TYPE__ size, void *p) +{ + return p; +} + +char heap[5000000]; + +int main () +{ + for (unsigned ix = sizeof (heap); ix--;) + heap[ix] = ix; + + foo *f = new (heap) foo (); + + if (!f->check ()) + return 1; + return 0; +} + + diff --git a/gcc/testsuite/g++.dg/init/array16.C b/gcc/testsuite/g++.dg/init/array16.C new file mode 100644 index 0000000..fa4c1b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array16.C @@ -0,0 +1,106 @@ +// { dg-do run } + +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 8 Dec 2004 <nathan@codesourcery.com> + +// PR 16681 too much memory used +// Origin: Matt LaFary <lafary@activmedia.com> + + +struct elt +{ + static int count; + static elt*ptr; + static int abort; + char c; + + elt (); + ~elt (); + +}; + +int elt::count; +elt *elt::ptr; +int elt::abort; + +elt::elt () + :c () +{ + if (count >= 0) + { + if (!ptr) + ptr = this; + if (count == 100) + throw 2; + if (this != ptr) + abort = 1; + count++; + ptr++; + } +} + +elt::~elt () +{ + if (count >= 0) + { + ptr--; + count--; + if (ptr != this) + abort = 2; + } +} + +struct foo { + elt buffer[4111222]; + foo() ; + bool check () const; +}; + +foo::foo () + : buffer() +{} + +bool foo::check () const +{ + for (unsigned ix = sizeof (buffer)/ sizeof (buffer[0]); ix--;) + if (buffer[ix].c) + return false; + return true; +} + +void *operator new (__SIZE_TYPE__ size, void *p) +{ + return p; +} + +char heap[5000000]; + +int main () +{ + for (unsigned ix = sizeof (heap); ix--;) + heap[ix] = ix; + + try + { + foo *f = new (heap) foo (); + return 1; + } + catch (...) + { + if (elt::count) + return 2; + if (elt::abort) + return elt::abort + 3; + } + + for (unsigned ix = sizeof (heap); ix--;) + heap[ix] = ix; + + elt::count = -1; + foo *f = new (heap) foo (); + if (!f->check ()) + return 3; + return 0; +} + + |