summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/init
diff options
context:
space:
mode:
authorfw <fw@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-25 17:03:10 +0000
committerfw <fw@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-25 17:03:10 +0000
commit653d8b92299e8d19a665c9fafa60493bbde37eba (patch)
tree6bc99a9a98432fdbf6966014f5b49826eca80801 /gcc/testsuite/g++.dg/init
parent425588b539280e2ad6c934ee6d255655bdc311bd (diff)
downloadgcc-653d8b92299e8d19a665c9fafa60493bbde37eba.tar.gz
C++: Reject variably modified types in operator new
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@188948 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite/g++.dg/init')
-rw-r--r--gcc/testsuite/g++.dg/init/new35.C13
-rw-r--r--gcc/testsuite/g++.dg/init/new36.C153
-rw-r--r--gcc/testsuite/g++.dg/init/new37.C63
3 files changed, 229 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/init/new35.C b/gcc/testsuite/g++.dg/init/new35.C
new file mode 100644
index 00000000000..c5f79aa2f80
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/new35.C
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "" }
+
+int
+main (int argc, char **argv)
+{
+ typedef char A[argc];
+ new A; // { dg-warning "variable-length array types|not a constant" }
+ new A[0]; // { dg-error "must be constant|not a constant" }
+ new A[5]; // { dg-error "must be constant|not a constant" }
+ new (A[0]); // { dg-error "must be constant|not a constant" }
+ new (A[5]); // { dg-error "must be constant|not a constant" }
+}
diff --git a/gcc/testsuite/g++.dg/init/new36.C b/gcc/testsuite/g++.dg/init/new36.C
new file mode 100644
index 00000000000..c9b7af2d871
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/new36.C
@@ -0,0 +1,153 @@
+// Testcase for invocation of constructors/destructors in operator new[].
+// { dg-do run }
+
+#include <stdlib.h>
+
+struct E {
+ virtual ~E() { }
+};
+
+struct S {
+ S();
+ ~S();
+};
+
+static int count;
+static int max;
+static int throwAfter = -1;
+static S *pS;
+
+S::S()
+{
+ if (throwAfter >= 0 && count >= throwAfter)
+ throw E();
+ if (pS)
+ {
+ ++pS;
+ if (this != pS)
+ abort();
+ }
+ else
+ pS = this;
+ ++count;
+ max = count;
+}
+
+S::~S()
+{
+ if (count > 1)
+ {
+ if (this != pS)
+ abort();
+ --pS;
+ }
+ else
+ pS = 0;
+ --count;
+}
+
+void __attribute__((noinline)) doit(int n)
+{
+ {
+ S *s = new S[n];
+ if (count != n)
+ abort();
+ if (pS != s + n - 1)
+ abort();
+ delete [] s;
+ if (count != 0)
+ abort();
+ }
+ throwAfter = 2;
+ max = 0;
+ try
+ {
+ new S[n];
+ abort();
+ }
+ catch (E)
+ {
+ if (max != 2)
+ abort();
+ }
+ throwAfter = -1;
+}
+
+int main()
+{
+ {
+ S s;
+ if (count != 1)
+ abort();
+ if (pS != &s)
+ abort();
+ }
+ if (count != 0)
+ abort();
+ {
+ S *s = new S;
+ if (count != 1)
+ abort();
+ if (pS != s)
+ abort();
+ delete s;
+ if (count != 0)
+ abort();
+ }
+ {
+ S *s = new S[1];
+ if (count != 1)
+ abort();
+ if (pS != s)
+ abort();
+ delete [] s;
+ if (count != 0)
+ abort();
+ }
+ {
+ S *s = new S[5];
+ if (count != 5)
+ abort();
+ if (pS != s + 4)
+ abort();
+ delete [] s;
+ if (count != 0)
+ abort();
+ }
+ typedef S A[5];
+ {
+ S *s = new A;
+ if (count != 5)
+ abort();
+ if (pS != s + 4)
+ abort();
+ delete [] s;
+ if (count != 0)
+ abort();
+ }
+ throwAfter = 2;
+ max = 0;
+ try
+ {
+ new S[5];
+ abort();
+ }
+ catch (E)
+ {
+ if (max != 2)
+ abort();
+ }
+ max = 0;
+ try
+ {
+ new A;
+ abort();
+ }
+ catch (E)
+ {
+ if (max != 2)
+ abort();
+ }
+ throwAfter = -1;
+ doit(5);
+}
diff --git a/gcc/testsuite/g++.dg/init/new37.C b/gcc/testsuite/g++.dg/init/new37.C
new file mode 100644
index 00000000000..82ca18b7aeb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/new37.C
@@ -0,0 +1,63 @@
+// { dg-do compile }
+
+void
+nonconst(int n)
+{
+ new (long[n][n]); // { dg-error "variable length|array size|not a constant" }
+ new long[n][n]; // { dg-error "variable length|array size|not a constant" }
+}
+
+template <typename T>
+void *
+callnew(int n)
+{
+ return new long[n][T::n];
+}
+
+template <typename T>
+void *
+callnew_fail_1(int n)
+{
+ return new long[n][T::n]; // { dg-error "variable length|array size|usable in a constant" }
+}
+
+template <typename T>
+void *
+callnew_fail_2()
+{
+ return new long[T::n]; // { dg-error "size in array new" }
+}
+
+template <typename T>
+void *
+callnew_fail_3()
+{
+ return new T[2][T::n]; // { dg-error "size of array has non-integral type" }
+}
+
+struct T1 {
+ static int n;
+};
+
+struct T2 {
+ static const double n = 2; // { dg-error "non-integral type" }
+};
+
+struct T3 {
+ static const int n = 2;
+};
+
+struct T4 {
+ enum { n = 3 };
+};
+
+void
+test_callnew(int n)
+{
+ new long[0.2]; // { dg-error "integral or enumeration type" }
+ callnew_fail_1<T1>(n);
+ callnew_fail_2<T2>();
+ callnew_fail_3<T2>();
+ callnew<T3>(n);
+ callnew<T4>(n);
+}