diff options
author | Kostya Serebryany <kcc@google.com> | 2014-08-04 10:10:50 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2014-08-04 10:10:50 +0000 |
commit | 1cd57ebb6b2ca7b2dbeb893664d59c0e1ae964d2 (patch) | |
tree | 5b975b1f6ce0f287686913799976685f246f3105 /compiler-rt | |
parent | 78cd5465f7d6d7864324ad7125a09660035a0058 (diff) | |
download | bcm5719-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.cc | 5 | ||||
-rw-r--r-- | compiler-rt/test/asan/TestCases/Linux/sized_delete_test.cc | 56 |
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. + } } |