1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
// RUN: %clangxx_asan -std=c++1z -faligned-allocation -fsanitize-recover=address -O0 %s -o %t
// RUN: %env_asan_opts=new_delete_type_mismatch=1:halt_on_error=false:detect_leaks=false %run %t 2>&1 | FileCheck %s
// RUN: %env_asan_opts=new_delete_type_mismatch=0 %run %t
// RUN: %clangxx_asan -std=c++1z -faligned-allocation -fsized-deallocation -fsanitize-recover=address -O0 %s -o %t
// RUN: %env_asan_opts=new_delete_type_mismatch=1:halt_on_error=false:detect_leaks=false %run %t 2>&1 | FileCheck %s
// RUN: %env_asan_opts=new_delete_type_mismatch=0 %run %t
#include <stdio.h>
// Define all new/delete to do not depend on the version provided by the
// platform. The implementation is provided by ASan anyway.
namespace std {
struct nothrow_t {};
static const nothrow_t nothrow;
enum class align_val_t : size_t {};
} // namespace std
void *operator new(size_t);
void *operator new[](size_t);
void *operator new(size_t, std::nothrow_t const&);
void *operator new[](size_t, std::nothrow_t const&);
void *operator new(size_t, std::align_val_t);
void *operator new[](size_t, std::align_val_t);
void *operator new(size_t, std::align_val_t, std::nothrow_t const&);
void *operator new[](size_t, std::align_val_t, std::nothrow_t const&);
void operator delete(void*) throw();
void operator delete[](void*) throw();
void operator delete(void*, std::nothrow_t const&);
void operator delete[](void*, std::nothrow_t const&);
void operator delete(void*, size_t) throw();
void operator delete[](void*, size_t) throw();
void operator delete(void*, std::align_val_t) throw();
void operator delete[](void*, std::align_val_t) throw();
void operator delete(void*, std::align_val_t, std::nothrow_t const&);
void operator delete[](void*, std::align_val_t, std::nothrow_t const&);
void operator delete(void*, size_t, std::align_val_t) throw();
void operator delete[](void*, size_t, std::align_val_t) throw();
template<typename T>
inline T* break_optimization(T *arg) {
__asm__ __volatile__("" : : "r" (arg) : "memory");
return arg;
}
struct S12 { int a, b, c; };
struct alignas(128) S12_128 { int a, b, c; };
struct alignas(256) S12_256 { int a, b, c; };
struct alignas(512) S1024_512 { char a[1024]; };
struct alignas(1024) S1024_1024 { char a[1024]; };
int main(int argc, char **argv) {
// Check the mismatched calls only, all the valid cases are verified in
// test/sanitizer_common/TestCases/Linux/new_delete_test.cpp.
operator delete(break_optimization(new S12_128), std::nothrow);
// CHECK: AddressSanitizer: new-delete-type-mismatch
// CHECK: object passed to delete has wrong type:
// CHECK: alignment of the allocated type: 128 bytes;
// CHECK: alignment of the deallocated type: default-aligned.
// CHECK: SUMMARY: AddressSanitizer: new-delete-type-mismatch
operator delete(break_optimization(new S12_128), sizeof(S12_128));
// CHECK: AddressSanitizer: new-delete-type-mismatch
// CHECK: object passed to delete has wrong type:
// CHECK: alignment of the allocated type: 128 bytes;
// CHECK: alignment of the deallocated type: default-aligned.
// CHECK: SUMMARY: AddressSanitizer: new-delete-type-mismatch
operator delete[](break_optimization(new S12_128[100]), std::nothrow);
// CHECK: AddressSanitizer: new-delete-type-mismatch
// CHECK: object passed to delete has wrong type:
// CHECK: alignment of the allocated type: 128 bytes;
// CHECK: alignment of the deallocated type: default-aligned.
// CHECK: SUMMARY: AddressSanitizer: new-delete-type-mismatch
operator delete[](break_optimization(new S12_128[100]), sizeof(S12_128[100]));
// CHECK: AddressSanitizer: new-delete-type-mismatch
// CHECK: object passed to delete has wrong type:
// CHECK: alignment of the allocated type: 128 bytes;
// CHECK: alignment of the deallocated type: default-aligned.
// CHECK: SUMMARY: AddressSanitizer: new-delete-type-mismatch
// Various mismatched alignments.
delete break_optimization(reinterpret_cast<S12*>(new S12_256));
// CHECK: AddressSanitizer: new-delete-type-mismatch
// CHECK: object passed to delete has wrong type:
// CHECK: alignment of the allocated type: 256 bytes;
// CHECK: alignment of the deallocated type: default-aligned.
// CHECK: SUMMARY: AddressSanitizer: new-delete-type-mismatch
delete break_optimization(reinterpret_cast<S12_256*>(new S12));
// CHECK: AddressSanitizer: new-delete-type-mismatch
// CHECK: object passed to delete has wrong type:
// CHECK: alignment of the allocated type: default-aligned;
// CHECK: alignment of the deallocated type: 256 bytes.
// CHECK: SUMMARY: AddressSanitizer: new-delete-type-mismatch
delete break_optimization(reinterpret_cast<S12_128*>(new S12_256));
// CHECK: AddressSanitizer: new-delete-type-mismatch
// CHECK: object passed to delete has wrong type:
// CHECK: alignment of the allocated type: 256 bytes;
// CHECK: alignment of the deallocated type: 128 bytes.
// CHECK: SUMMARY: AddressSanitizer: new-delete-type-mismatch
delete [] break_optimization(reinterpret_cast<S12*>(new S12_256[100]));
// CHECK: AddressSanitizer: new-delete-type-mismatch
// CHECK: object passed to delete has wrong type:
// CHECK: alignment of the allocated type: 256 bytes;
// CHECK: alignment of the deallocated type: default-aligned.
// CHECK: SUMMARY: AddressSanitizer: new-delete-type-mismatch
delete [] break_optimization(reinterpret_cast<S12_256*>(new S12[100]));
// CHECK: AddressSanitizer: new-delete-type-mismatch
// CHECK: object passed to delete has wrong type:
// CHECK: alignment of the allocated type: default-aligned;
// CHECK: alignment of the deallocated type: 256 bytes.
// CHECK: SUMMARY: AddressSanitizer: new-delete-type-mismatch
delete [] break_optimization(reinterpret_cast<S12_128*>(new S12_256[100]));
// CHECK: AddressSanitizer: new-delete-type-mismatch
// CHECK: object passed to delete has wrong type:
// CHECK: alignment of the allocated type: 256 bytes;
// CHECK: alignment of the deallocated type: 128 bytes.
// CHECK: SUMMARY: AddressSanitizer: new-delete-type-mismatch
// Push ASan limits, the current limitation is that it cannot differentiate
// alignments above 512 bytes.
fprintf(stderr, "Checking alignments >= 512 bytes\n");
delete break_optimization(reinterpret_cast<S1024_512*>(new S1024_1024));
fprintf(stderr, "Done\n");
// CHECK: Checking alignments >= 512 bytes
// CHECK-NEXT: Done
}
|