aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2004-12-09 09:37:37 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2004-12-09 09:37:37 +0000
commit9476364759b1dc6e0f79b381b6adb7f995cc2706 (patch)
treec90b357b9524e70af672bd367baeefb8eeb3758d /gcc
parent42fabf21b2167ab9d0fc8482b297a7e75ff2964f (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/init.c19
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/init/array15.C46
-rw-r--r--gcc/testsuite/g++.dg/init/array16.C106
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;
+}
+
+