summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2014-08-04 10:10:50 +0000
committerKostya Serebryany <kcc@google.com>2014-08-04 10:10:50 +0000
commit1cd57ebb6b2ca7b2dbeb893664d59c0e1ae964d2 (patch)
tree5b975b1f6ce0f287686913799976685f246f3105 /compiler-rt
parent78cd5465f7d6d7864324ad7125a09660035a0058 (diff)
downloadbcm5719-llvm-1cd57ebb6b2ca7b2dbeb893664d59c0e1ae964d2.tar.gz
bcm5719-llvm-1cd57ebb6b2ca7b2dbeb893664d59c0e1ae964d2.zip
[asan] intercept sized operator delete[]
llvm-svn: 214704
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/lib/asan/asan_new_delete.cc5
-rw-r--r--compiler-rt/test/asan/TestCases/Linux/sized_delete_test.cc56
2 files changed, 47 insertions, 14 deletions
diff --git a/compiler-rt/lib/asan/asan_new_delete.cc b/compiler-rt/lib/asan/asan_new_delete.cc
index 859d86c4e7b..242760275fe 100644
--- a/compiler-rt/lib/asan/asan_new_delete.cc
+++ b/compiler-rt/lib/asan/asan_new_delete.cc
@@ -110,6 +110,11 @@ void operator delete(void *ptr, size_t size) throw() {
GET_STACK_TRACE_FREE;
asan_sized_free(ptr, size, &stack, FROM_NEW);
}
+CXX_OPERATOR_ATTRIBUTE
+void operator delete[](void *ptr, size_t size) throw() {
+ GET_STACK_TRACE_FREE;
+ asan_sized_free(ptr, size, &stack, FROM_NEW_BR);
+}
#else // SANITIZER_MAC
INTERCEPTOR(void, _ZdlPv, void *ptr) {
diff --git a/compiler-rt/test/asan/TestCases/Linux/sized_delete_test.cc b/compiler-rt/test/asan/TestCases/Linux/sized_delete_test.cc
index a8e0b8b09c7..823e3c0bf88 100644
--- a/compiler-rt/test/asan/TestCases/Linux/sized_delete_test.cc
+++ b/compiler-rt/test/asan/TestCases/Linux/sized_delete_test.cc
@@ -1,7 +1,10 @@
// RUN: %clangxx_asan -Xclang -fsized-deallocation -O0 %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=new_delete_type_mismatch=1 not %run %t 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=new_delete_type_mismatch=0 %run %t
+// RUN: not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR
+// RUN: ASAN_OPTIONS=new_delete_type_mismatch=1 not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR
+// RUN: not %run %t array 2>&1 | FileCheck %s -check-prefix=ARRAY
+// RUN: ASAN_OPTIONS=new_delete_type_mismatch=1 not %run %t array 2>&1 | FileCheck %s -check-prefix=ARRAY
+// RUN: ASAN_OPTIONS=new_delete_type_mismatch=0 %run %t scalar
+// RUN: ASAN_OPTIONS=new_delete_type_mismatch=0 %run %t array
// Sized-delete is implemented with a weak delete() definition.
// Weak symbols are kind of broken on Android.
@@ -9,6 +12,7 @@
#include <new>
#include <stdio.h>
+#include <string>
inline void break_optimization(void *arg) {
__asm__ __volatile__("" : : "r" (arg) : "memory");
@@ -22,6 +26,16 @@ struct S20 {
int a, b, c, d, e;
};
+struct D1 {
+ int a, b, c;
+ ~D1() { fprintf(stderr, "D1::~D1\n"); }
+};
+
+struct D2 {
+ int a, b, c, d, e;
+ ~D2() { fprintf(stderr, "D2::~D2\n"); }
+};
+
void Del12(S12 *x) {
break_optimization(x);
delete x;
@@ -39,7 +53,9 @@ void Del12ArNoThrow(S12 *x) {
operator delete[](x, std::nothrow);
}
-int main() {
+int main(int argc, char **argv) {
+ if (argc != 2) return 1;
+ std::string flag = argv[1];
// These are correct.
Del12(new S12);
Del12NoThrow(new S12);
@@ -52,14 +68,26 @@ int main() {
Del12NoThrow(reinterpret_cast<S12*>(new S20));
Del12ArNoThrow(reinterpret_cast<S12*>(new S20[100]));
fprintf(stderr, "OK SO FAR\n");
- // CHECK: OK SO FAR
- // Here asan should bark as we are passing a wrong type of pointer
- // to sized delete.
- Del12(reinterpret_cast<S12*>(new S20));
- // CHECK: AddressSanitizer: new-delete-type-mismatch
- // CHECK: object passed to delete has wrong type:
- // CHECK: size of the allocated type: 20 bytes;
- // CHECK: size of the deallocated type: 12 bytes.
- // CHECK: is located 0 bytes inside of 20-byte region
- // CHECK: SUMMARY: AddressSanitizer: new-delete-type-mismatch
+ // SCALAR: OK SO FAR
+ // ARRAY: OK SO FAR
+ if (flag == "scalar") {
+ // Here asan should bark as we are passing a wrong type of pointer
+ // to sized delete.
+ Del12(reinterpret_cast<S12*>(new S20));
+ // SCALAR: AddressSanitizer: new-delete-type-mismatch
+ // SCALAR: object passed to delete has wrong type:
+ // SCALAR: size of the allocated type: 20 bytes;
+ // SCALAR: size of the deallocated type: 12 bytes.
+ // SCALAR: is located 0 bytes inside of 20-byte region
+ // SCALAR: SUMMARY: AddressSanitizer: new-delete-type-mismatch
+ } else if (flag == "array") {
+ D1 *d1 = reinterpret_cast<D1*>(new D2[10]);
+ break_optimization(d1);
+ delete [] d1;
+ // ARRAY-NOT: D2::~D2
+ // ARRAY: D1::~D1
+ // ARRAY: AddressSanitizer: new-delete-type-mismatch
+ // ARRAY: size of the allocated type: 20{{4|8}} bytes;
+ // ARRAY: size of the deallocated type: 12{{4|8}} bytes.
+ }
}
OpenPOWER on IntegriCloud