aboutsummaryrefslogtreecommitdiff
path: root/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cc')
-rw-r--r--test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cc38
1 files changed, 38 insertions, 0 deletions
diff --git a/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cc b/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cc
new file mode 100644
index 000000000000..1cea6f68adb2
--- /dev/null
+++ b/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cc
@@ -0,0 +1,38 @@
+// Test that we do not poison the array cookie if the operator new is defined
+// inside the class.
+// RUN: %clangxx_asan %s -o %t && %run %t
+//
+// XFAIL: android
+// XFAIL: armv7l-unknown-linux-gnueabihf
+#include <new>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+struct Foo {
+ void *operator new(size_t s) { return Allocate(s); }
+ void *operator new[] (size_t s) { return Allocate(s); }
+ ~Foo();
+ static void *allocated;
+ static void *Allocate(size_t s) {
+ assert(!allocated);
+ return allocated = ::new char[s];
+ }
+};
+
+Foo::~Foo() {}
+void *Foo::allocated;
+
+Foo *getFoo(size_t n) {
+ return new Foo[n];
+}
+
+int main() {
+ Foo *foo = getFoo(10);
+ fprintf(stderr, "foo : %p\n", foo);
+ fprintf(stderr, "alloc: %p\n", Foo::allocated);
+ assert(reinterpret_cast<uintptr_t>(foo) ==
+ reinterpret_cast<uintptr_t>(Foo::allocated) + sizeof(void*));
+ *reinterpret_cast<uintptr_t*>(Foo::allocated) = 42;
+ return 0;
+}