From 93af82a06d545a58510f2a520a1672d455ac6339 Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 9 Dec 2004 09:37:37 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91928 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 ++ gcc/cp/init.c | 19 ++++--- gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/g++.dg/init/array15.C | 46 ++++++++++++++++ gcc/testsuite/g++.dg/init/array16.C | 106 ++++++++++++++++++++++++++++++++++++ 5 files changed, 174 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/init/array15.C create mode 100644 gcc/testsuite/g++.dg/init/array16.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d37b9631dfd..2d73639bce1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-12-09 Nathan Sidwell + + PR c++/16681 + * init.c (build_zero_init): Build a RANGE_EXPR for an array + initializer. + 2004-12-08 Kelley Cook * typeck.c: Remove DOS line endings. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 95b57b2e8ef..70703efacac 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 f946bf10399..d8ad0adbf58 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2004-12-09 Nathan Sidwell + + PR c++/16681 + * g++.dg/init/array15.C: New. + * g++.dg/init/array16.C: New. + 2004-12-08 Tobias Schlueter 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 00000000000..17160d07611 --- /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 + +// PR 16681 too much memory used +// Origin: Matt LaFary + +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 00000000000..fa4c1b65088 --- /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 + +// PR 16681 too much memory used +// Origin: Matt LaFary + + +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; +} + + -- 2.11.0