summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.old-deja/g++.abi/arraynew.C
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/g++.old-deja/g++.abi/arraynew.C')
-rw-r--r--gcc/testsuite/g++.old-deja/g++.abi/arraynew.C152
1 files changed, 152 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C b/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C
new file mode 100644
index 000000000..ff19c7e37
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C
@@ -0,0 +1,152 @@
+// { dg-do run }
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
+
+#include <cstdlib>
+#include <new>
+
+void* p;
+
+void* operator new[](size_t s) throw (std::bad_alloc)
+{
+ // Record the base of the last array allocated.
+ p = malloc (s);
+ return p;
+}
+
+template <typename T>
+void check_no_cookie (int i)
+{
+ void* a = new T[7];
+ if (p != a)
+ exit (i);
+}
+
+template <typename T>
+void check_no_placement_cookie (int i)
+{
+ p = malloc (13 * sizeof (T));
+ void* a = new (p) T[13];
+ if (p != a)
+ exit (i);
+}
+
+template <typename T>
+void check_cookie (int i)
+{
+ void* a = new T[11];
+ size_t x;
+
+ // Compute the cookie location manually.
+#ifdef __ARM_EABI__
+ x = 8;
+#else
+ x = __alignof__ (T);
+ if (x < sizeof (size_t))
+ x = sizeof (size_t);
+#endif
+ if ((char *) a - x != (char *) p)
+ exit (i);
+
+ // Check the cookie value.
+ size_t *sp = ((size_t *) a) - 1;
+ if (*sp != 11)
+ exit (i);
+
+#ifdef __ARM_EABI__
+ sp = ((size_t *) a) - 2;
+ if (*sp != sizeof (T))
+ exit (i);
+#endif
+}
+
+template <typename T>
+void check_placement_cookie (int i)
+{
+ p = malloc (sizeof (T) * 11 + 100);
+ void* a = new (p) T[11];
+ size_t x;
+
+ // Compute the cookie location manually.
+#ifdef __ARM_EABI__
+ x = 8;
+#else
+ x = __alignof__ (T);
+ if (x < sizeof (size_t))
+ x = sizeof (size_t);
+#endif
+ if ((char *) a - x != (char *) p)
+ exit (i);
+
+ // Check the cookie value.
+ size_t *sp = ((size_t *) a) - 1;
+ if (*sp != 11)
+ exit (i);
+
+#ifdef __ARM_EABI__
+ sp = ((size_t *) a) - 2;
+ if (*sp != sizeof (T))
+ exit (i);
+#endif
+}
+
+struct X {};
+
+template <typename T>
+struct Y { int i; virtual void f () {} };
+
+// A class with a non-trivial destructor -- it needs a cookie.
+struct Z { ~Z () {} };
+// Likewise, but this class needs a bigger cookie so that the array
+// elements are correctly aligned.
+struct Z2 { ~Z2 () {} long double d; };
+
+struct W1 { void operator delete[] (void *, size_t) {} };
+struct W2 { void operator delete[] (void *) {}
+ void operator delete[] (void *, size_t) {} };
+struct W3 { void operator delete[] (void *, size_t) {}
+ void operator delete[] (void *) {} };
+struct W4 : public W1 {};
+
+struct V { void *operator new[] (size_t s, void *p)
+ { return p; }
+ ~V () {}
+ };
+
+int main ()
+{
+ // There should be no cookies for types with trivial destructors.
+ check_no_cookie<int> (1);
+ check_no_cookie<X> (2);
+ check_no_cookie<Y<double> > (3);
+
+ // There should be no cookies for allocations using global placement
+ // new.
+ check_no_placement_cookie<int> (4);
+ check_no_placement_cookie<X> (5);
+ check_no_placement_cookie<Z> (6);
+
+ // There should be a cookie when using a non-trivial destructor.
+ check_cookie<Z> (7);
+ check_cookie<Z2> (8);
+
+ // There should be a cookie when using the two-argument array delete
+ // operator.
+ check_cookie<W1> (9);
+ check_cookie<W4> (10);
+ // But not when the one-argument version is also available.
+ check_no_cookie<W2> (11);
+ check_no_cookie<W3> (12);
+
+ // There should be a cookie when using a non-global placement new.
+ check_placement_cookie<V> (13);
+}
+
+#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
+
+int main ()
+{
+}
+
+#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */