From: Matt Austern Date: Fri, 20 Jun 2003 00:33:58 +0000 (+0000) Subject: Fix for PR c++/11228, infinite loop for new int[n](). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7a1d37e9102a1bbc34b4544161ddf283c667bc0b;p=gcc.git Fix for PR c++/11228, infinite loop for new int[n](). From-SVN: r68235 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0b620d69462..ba1fb358846 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2003-06-19 Matt Austern + + PR c++/11228 + * init.c (build_zero_init): Assert that number of array elements + is an integer constant. + (build_default_init) Don't use build_zero_init for arrays with + variable number of elements. + 2003-06-19 Andreas Jaeger * cp-tree.h: Remove duplicated declarations. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 59395eed1d0..710f6174413 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -180,6 +180,9 @@ build_zero_init (tree type, tree nelts, bool static_storage_p) -- if T is a reference type, no initialization is performed. */ + my_friendly_assert (nelts == NULL_TREE || TREE_CODE (nelts) == INTEGER_CST, + 20030618); + if (type == error_mark_node) ; else if (static_storage_p && zero_init_p (type)) @@ -232,6 +235,8 @@ build_zero_init (tree type, tree nelts, bool static_storage_p) /* Iterate over the array elements, building initializations. */ inits = NULL_TREE; max_index = nelts ? nelts : array_type_nelts (type); + my_friendly_assert (TREE_CODE (max_index) == INTEGER_CST, 20030618); + for (index = size_zero_node; !tree_int_cst_lt (max_index, index); index = size_binop (PLUS_EXPR, index, size_one_node)) @@ -291,7 +296,8 @@ build_default_init (tree type, tree nelts) standard says we should have generated would be precisely the same as that obtained by calling build_zero_init below, so things work out OK. */ - if (TYPE_NEEDS_CONSTRUCTING (type)) + if (TYPE_NEEDS_CONSTRUCTING (type) + || (nelts && TREE_CODE (nelts) != INTEGER_CST)) return NULL_TREE; /* At this point, TYPE is either a POD class type, an array of POD diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4c848dda2dc..2a1363af422 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2003-06-19 Matt Austern + + PR c++/11228 + * g++.dg/anew1.C: New test. + * g++.dg/anew2.C: New test. + * g++.dg/anew3.C: New test. + * g++.dg/anew4.C: New test. + 2003-06-19 Kazu Hirata * gcc.c-torture/compile/simd-5.c: Don't XFAIL on H8. diff --git a/gcc/testsuite/g++.dg/expr/anew1.C b/gcc/testsuite/g++.dg/expr/anew1.C new file mode 100644 index 00000000000..a14408ace0a --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/anew1.C @@ -0,0 +1,20 @@ +// { dg-do run } +// PR 11228: array operator new, with zero-initialization and a variable sized array. +// Regression test for PR +// Author: Matt Austern + + +int* allocate(int n) +{ + return new int[n](); +} + +int main() +{ + const int n = 17; + int* p = allocate(n); + for (int i = 0; i < n; ++i) + if (p[i] != 0) + return 1; + return 0; +} diff --git a/gcc/testsuite/g++.dg/expr/anew2.C b/gcc/testsuite/g++.dg/expr/anew2.C new file mode 100644 index 00000000000..b8681897577 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/anew2.C @@ -0,0 +1,20 @@ +// { dg-do run } +// PR 11228: array operator new, with zero-initialization and a variable sized array. +// Regression test for PR +// Author: Matt Austern + + +double* allocate(int n) +{ + return new double[n](); +} + +int main() +{ + const int n = 17; + double* p = allocate(n); + for (int i = 0; i < n; ++i) + if (p[i] != 0.0) + return 1; + return 0; +} diff --git a/gcc/testsuite/g++.dg/expr/anew3.C b/gcc/testsuite/g++.dg/expr/anew3.C new file mode 100644 index 00000000000..3223546d4c8 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/anew3.C @@ -0,0 +1,25 @@ +// { dg-do run } +// PR 11228: array operator new, with zero-initialization and a variable sized array. +// Regression test for PR +// Author: Matt Austern + +struct X +{ + int a; + double b; +}; + +X* allocate(int n) +{ + return new X[n](); +} + +int main() +{ + const int n = 17; + X* p = allocate(n); + for (int i = 0; i < n; ++i) + if (p[i].a != 0 || p[i].b != 0.0) + return 1; + return 0; +} diff --git a/gcc/testsuite/g++.dg/expr/anew4.C b/gcc/testsuite/g++.dg/expr/anew4.C new file mode 100644 index 00000000000..8999ffb53c6 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/anew4.C @@ -0,0 +1,37 @@ +// { dg-do run } +// PR 11228: array operator new, with zero-initialization and a variable sized array. +// Regression test for PR +// Author: Matt Austern + +struct B +{ + B(); + int n; +}; + +B::B() +{ + n = 137; +} + + +struct D : public B +{ + double x; +}; + + +D* allocate(int n) +{ + return new D[n](); +} + +int main() +{ + const int n = 17; + D* p = allocate(n); + for (int i = 0; i < n; ++i) + if (p[i].n != 137 || p[i].x != 0) + return 1; + return 0; +}