Index: compiler-rt/trunk/test/asan/TestCases/allocator_returns_null.cc =================================================================== --- compiler-rt/trunk/test/asan/TestCases/allocator_returns_null.cc +++ compiler-rt/trunk/test/asan/TestCases/allocator_returns_null.cc @@ -1,133 +0,0 @@ -// Test the behavior of malloc/calloc/realloc/new when the allocation size is -// more than ASan allocator's max allowed one. -// By default (allocator_may_return_null=0) the process should crash. -// With allocator_may_return_null=1 the allocator should return 0, except the -// operator new(), which should crash anyway (operator new(std::nothrow) should -// return nullptr, indeed). -// -// RUN: %clangxx_asan -O0 %s -o %t -// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mNULL -// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-cCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t calloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-cNULL -// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-coCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-coNULL -// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-rCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t realloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-rNULL -// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mrCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mrNULL -// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t new 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 not %run %t new 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH-OOM -// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nnNULL - -// UNSUPPORTED: win32 - -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char **argv) { - // Disable stderr buffering. Needed on Windows. - setvbuf(stderr, NULL, _IONBF, 0); - - assert(argc == 2); - const char *action = argv[1]; - fprintf(stderr, "%s:\n", action); - - static const size_t kMaxAllowedMallocSizePlusOne = -#if __LP64__ || defined(_WIN64) - (1ULL << 40) + 1; -#else - (3UL << 30) + 1; -#endif - - void *x = 0; - if (!strcmp(action, "malloc")) { - x = malloc(kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "calloc")) { - x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4); - } else if (!strcmp(action, "calloc-overflow")) { - volatile size_t kMaxSizeT = std::numeric_limits::max(); - size_t kArraySize = 4096; - volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; - x = calloc(kArraySize, kArraySize2); - } else if (!strcmp(action, "realloc")) { - x = realloc(0, kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "realloc-after-malloc")) { - char *t = (char*)malloc(100); - *t = 42; - x = realloc(t, kMaxAllowedMallocSizePlusOne); - assert(*t == 42); - free(t); - } else if (!strcmp(action, "new")) { - x = operator new(kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "new-nothrow")) { - x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow); - } else { - assert(0); - } - - fprintf(stderr, "errno: %d\n", errno); - - // The NULL pointer is printed differently on different systems, while (long)0 - // is always the same. - fprintf(stderr, "x: %lx\n", (long)x); - free(x); - - return x != 0; -} - -// CHECK-mCRASH: malloc: -// CHECK-mCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big -// CHECK-cCRASH: calloc: -// CHECK-cCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big -// CHECK-coCRASH: calloc-overflow: -// CHECK-coCRASH: SUMMARY: AddressSanitizer: calloc-overflow -// CHECK-rCRASH: realloc: -// CHECK-rCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big -// CHECK-mrCRASH: realloc-after-malloc: -// CHECK-mrCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big -// CHECK-nCRASH: new: -// CHECK-nCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big -// CHECK-nCRASH-OOM: new: -// CHECK-nCRASH-OOM: SUMMARY: AddressSanitizer: out-of-memory -// CHECK-nnCRASH: new-nothrow: -// CHECK-nnCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big - -// CHECK-mNULL: malloc: -// CHECK-mNULL: errno: 12 -// CHECK-mNULL: x: 0 -// CHECK-cNULL: calloc: -// CHECK-cNULL: errno: 12 -// CHECK-cNULL: x: 0 -// CHECK-coNULL: calloc-overflow: -// CHECK-coNULL: errno: 12 -// CHECK-coNULL: x: 0 -// CHECK-rNULL: realloc: -// CHECK-rNULL: errno: 12 -// CHECK-rNULL: x: 0 -// CHECK-mrNULL: realloc-after-malloc: -// CHECK-mrNULL: errno: 12 -// CHECK-mrNULL: x: 0 -// CHECK-nnNULL: new-nothrow: -// CHECK-nnNULL: x: 0 Index: compiler-rt/trunk/test/lsan/TestCases/allocator_returns_null.cc =================================================================== --- compiler-rt/trunk/test/lsan/TestCases/allocator_returns_null.cc +++ compiler-rt/trunk/test/lsan/TestCases/allocator_returns_null.cc @@ -1,133 +0,0 @@ -// Test the behavior of malloc/calloc/realloc/new when the allocation size is -// more than LSan allocator's max allowed one. -// By default (allocator_may_return_null=0) the process should crash. -// With allocator_may_return_null=1 the allocator should return 0, except the -// operator new(), which should crash anyway (operator new(std::nothrow) should -// return nullptr, indeed). -// -// RUN: %clangxx_lsan -O0 %s -o %t -// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mNULL -// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-cCRASH -// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t calloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-cNULL -// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-coCRASH -// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-coNULL -// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-rCRASH -// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t realloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-rNULL -// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mrCRASH -// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mrNULL -// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t new 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH -// RUN: %env_lsan_opts=allocator_may_return_null=1 not %run %t new 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH-OOM -// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH -// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nnNULL - -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char **argv) { - // Disable stderr buffering. Needed on Windows. - setvbuf(stderr, NULL, _IONBF, 0); - - assert(argc == 2); - const char *action = argv[1]; - fprintf(stderr, "%s:\n", action); - - // Use max of ASan and LSan allocator limits to cover both "lsan" and - // "lsan + asan" configs. - static const size_t kMaxAllowedMallocSizePlusOne = -#if __LP64__ || defined(_WIN64) - (1ULL << 40) + 1; -#else - (3UL << 30) + 1; -#endif - - void *x = 0; - if (!strcmp(action, "malloc")) { - x = malloc(kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "calloc")) { - x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4); - } else if (!strcmp(action, "calloc-overflow")) { - volatile size_t kMaxSizeT = std::numeric_limits::max(); - size_t kArraySize = 4096; - volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; - x = calloc(kArraySize, kArraySize2); - } else if (!strcmp(action, "realloc")) { - x = realloc(0, kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "realloc-after-malloc")) { - char *t = (char*)malloc(100); - *t = 42; - x = realloc(t, kMaxAllowedMallocSizePlusOne); - assert(*t == 42); - free(t); - } else if (!strcmp(action, "new")) { - x = operator new(kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "new-nothrow")) { - x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow); - } else { - assert(0); - } - - fprintf(stderr, "errno: %d\n", errno); - - // The NULL pointer is printed differently on different systems, while (long)0 - // is always the same. - fprintf(stderr, "x: %zu\n", (size_t)x); - free(x); - - return x != 0; -} - -// CHECK-mCRASH: malloc: -// CHECK-mCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} -// CHECK-cCRASH: calloc: -// CHECK-cCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} -// CHECK-coCRASH: calloc-overflow: -// CHECK-coCRASH: {{SUMMARY: .*Sanitizer: calloc-overflow}} -// CHECK-rCRASH: realloc: -// CHECK-rCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} -// CHECK-mrCRASH: realloc-after-malloc: -// CHECK-mrCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} -// CHECK-nCRASH: new: -// CHECK-nCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} -// CHECK-nCRASH-OOM: new: -// CHECK-nCRASH-OOM: {{SUMMARY: .*Sanitizer: out-of-memory}} -// CHECK-nnCRASH: new-nothrow: -// CHECK-nnCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} - -// CHECK-mNULL: malloc: -// CHECK-mNULL: errno: 12 -// CHECK-mNULL: x: 0 -// CHECK-cNULL: calloc: -// CHECK-cNULL: errno: 12 -// CHECK-cNULL: x: 0 -// CHECK-coNULL: calloc-overflow: -// CHECK-coNULL: errno: 12 -// CHECK-coNULL: x: 0 -// CHECK-rNULL: realloc: -// CHECK-rNULL: errno: 12 -// CHECK-rNULL: x: 0 -// CHECK-mrNULL: realloc-after-malloc: -// CHECK-mrNULL: errno: 12 -// CHECK-mrNULL: x: 0 -// CHECK-nnNULL: new-nothrow: -// CHECK-nnNULL: x: 0 Index: compiler-rt/trunk/test/msan/allocator_returns_null.cc =================================================================== --- compiler-rt/trunk/test/msan/allocator_returns_null.cc +++ compiler-rt/trunk/test/msan/allocator_returns_null.cc @@ -1,133 +0,0 @@ -// Test the behavior of malloc/calloc/realloc/new when the allocation size is -// more than MSan allocator's max allowed one. -// By default (allocator_may_return_null=0) the process should crash. -// With allocator_may_return_null=1 the allocator should return 0, except the -// operator new(), which should crash anyway (operator new(std::nothrow) should -// return nullptr, indeed). -// -// RUN: %clangxx_msan -O0 %s -o %t -// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mNULL -// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-cCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t calloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-cNULL -// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-coCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-coNULL -// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-rCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t realloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-rNULL -// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mrCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-mrNULL -// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t new 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 not %run %t new 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH-OOM -// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nnNULL - -// UNSUPPORTED: win32 - -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char **argv) { - // Disable stderr buffering. Needed on Windows. - setvbuf(stderr, NULL, _IONBF, 0); - - assert(argc == 2); - const char *action = argv[1]; - fprintf(stderr, "%s:\n", action); - - static const size_t kMaxAllowedMallocSizePlusOne = -#if __LP64__ || defined(_WIN64) - (8UL << 30) + 1; -#else - (2UL << 30) + 1; -#endif - - void *x = 0; - if (!strcmp(action, "malloc")) { - x = malloc(kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "calloc")) { - x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4); - } else if (!strcmp(action, "calloc-overflow")) { - volatile size_t kMaxSizeT = std::numeric_limits::max(); - size_t kArraySize = 4096; - volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; - x = calloc(kArraySize, kArraySize2); - } else if (!strcmp(action, "realloc")) { - x = realloc(0, kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "realloc-after-malloc")) { - char *t = (char*)malloc(100); - *t = 42; - x = realloc(t, kMaxAllowedMallocSizePlusOne); - assert(*t == 42); - free(t); - } else if (!strcmp(action, "new")) { - x = operator new(kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "new-nothrow")) { - x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow); - } else { - assert(0); - } - - fprintf(stderr, "errno: %d\n", errno); - - // The NULL pointer is printed differently on different systems, while (long)0 - // is always the same. - fprintf(stderr, "x: %lx\n", (long)x); - free(x); - - return x != 0; -} - -// CHECK-mCRASH: malloc: -// CHECK-mCRASH: SUMMARY: MemorySanitizer: allocation-size-too-big -// CHECK-cCRASH: calloc: -// CHECK-cCRASH: SUMMARY: MemorySanitizer: allocation-size-too-big -// CHECK-coCRASH: calloc-overflow: -// CHECK-coCRASH: SUMMARY: MemorySanitizer: calloc-overflow -// CHECK-rCRASH: realloc: -// CHECK-rCRASH: SUMMARY: MemorySanitizer: allocation-size-too-big -// CHECK-mrCRASH: realloc-after-malloc: -// CHECK-mrCRASH: SUMMARY: MemorySanitizer: allocation-size-too-big -// CHECK-nCRASH: new: -// CHECK-nCRASH: SUMMARY: MemorySanitizer: allocation-size-too-big -// CHECK-nCRASH-OOM: new: -// CHECK-nCRASH-OOM: SUMMARY: MemorySanitizer: out-of-memory -// CHECK-nnCRASH: new-nothrow: -// CHECK-nnCRASH: SUMMARY: MemorySanitizer: allocation-size-too-big - -// CHECK-mNULL: malloc: -// CHECK-mNULL: errno: 12 -// CHECK-mNULL: x: 0 -// CHECK-cNULL: calloc: -// CHECK-cNULL: errno: 12 -// CHECK-cNULL: x: 0 -// CHECK-coNULL: calloc-overflow: -// CHECK-coNULL: errno: 12 -// CHECK-coNULL: x: 0 -// CHECK-rNULL: realloc: -// CHECK-rNULL: errno: 12 -// CHECK-rNULL: x: 0 -// CHECK-mrNULL: realloc-after-malloc: -// CHECK-mrNULL: errno: 12 -// CHECK-mrNULL: x: 0 -// CHECK-nnNULL: new-nothrow: -// CHECK-nnNULL: x: 0 Index: compiler-rt/trunk/test/sanitizer_common/TestCases/allocator_returns_null.cc =================================================================== --- compiler-rt/trunk/test/sanitizer_common/TestCases/allocator_returns_null.cc +++ compiler-rt/trunk/test/sanitizer_common/TestCases/allocator_returns_null.cc @@ -0,0 +1,118 @@ +// Test the behavior of malloc/calloc/realloc/new when the allocation size +// exceeds the sanitizer's allocator max allowed one. +// By default (allocator_may_return_null=0) the process should crash. With +// allocator_may_return_null=1 the allocator should return 0 and set errno to +// the appropriate error code. +// +// RUN: %clangxx -O0 %s -o %t +// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH +// RUN: %tool_options=allocator_may_return_null=0 not %run %t malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-mCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %tool_options=allocator_may_return_null=0 not %run %t calloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-cCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t calloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %tool_options=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-coCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %tool_options=allocator_may_return_null=0 not %run %t realloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-rCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t realloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %tool_options=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-mrCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %tool_options=allocator_may_return_null=0 not %run %t new 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH +// RUN: %tool_options=allocator_may_return_null=1 not %run %t new 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH-OOM +// RUN: %tool_options=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL + +// TODO(alekseyshl): win32 is disabled due to failing errno tests, fix it there. +// UNSUPPORTED: tsan, ubsan, win32 + +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + assert(argc == 2); + const char *action = argv[1]; + fprintf(stderr, "%s:\n", action); + + // The maximum value of all supported sanitizers: + // ASan: asan_allocator.cc, search for kMaxAllowedMallocSize. + // LSan: lsan_allocator.cc, search for kMaxAllowedMallocSize. + // ASan + LSan: ASan limit is used. + // MSan: msan_allocator.cc, search for kMaxAllowedMallocSize. + // TSan: tsan_mman.cc, user_alloc_internal function. + static const size_t kMaxAllowedMallocSizePlusOne = +#if __LP64__ || defined(_WIN64) + (1ULL << 40) + 1; +#else + (3UL << 30) + 1; +#endif + + void *x = nullptr; + if (!strcmp(action, "malloc")) { + x = malloc(kMaxAllowedMallocSizePlusOne); + } else if (!strcmp(action, "calloc")) { + x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4); + } else if (!strcmp(action, "calloc-overflow")) { + volatile size_t kMaxSizeT = std::numeric_limits::max(); + size_t kArraySize = 4096; + volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; + x = calloc(kArraySize, kArraySize2); + } else if (!strcmp(action, "realloc")) { + x = realloc(0, kMaxAllowedMallocSizePlusOne); + } else if (!strcmp(action, "realloc-after-malloc")) { + char *t = (char*)malloc(100); + *t = 42; + x = realloc(t, kMaxAllowedMallocSizePlusOne); + assert(*t == 42); + free(t); + } else if (!strcmp(action, "new")) { + x = operator new(kMaxAllowedMallocSizePlusOne); + } else if (!strcmp(action, "new-nothrow")) { + x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow); + } else { + assert(0); + } + + fprintf(stderr, "errno: %d\n", errno); + + free(x); + + return x != nullptr; +} + +// CHECK-mCRASH: malloc: +// CHECK-mCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} +// CHECK-cCRASH: calloc: +// CHECK-cCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} +// CHECK-coCRASH: calloc-overflow: +// CHECK-coCRASH: {{SUMMARY: .*Sanitizer: calloc-overflow}} +// CHECK-rCRASH: realloc: +// CHECK-rCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} +// CHECK-mrCRASH: realloc-after-malloc: +// CHECK-mrCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} +// CHECK-nCRASH: new: +// CHECK-nCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} +// CHECK-nCRASH-OOM: new: +// CHECK-nCRASH-OOM: {{SUMMARY: .*Sanitizer: out-of-memory}} +// CHECK-nnCRASH: new-nothrow: +// CHECK-nnCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} + +// CHECK-NULL: {{malloc|calloc|calloc-overflow|realloc|realloc-after-malloc|new-nothrow}} +// CHECK-NULL: errno: 12