diff options
Diffstat (limited to 'test')
21 files changed, 536 insertions, 193 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7685fb3f426f..9b4759dfb8d4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -35,6 +35,16 @@ if(NOT ANDROID) endif() endif() +function(compiler_rt_test_runtime runtime) + string(TOUPPER ${runtime} runtime_uppercase) + if(COMPILER_RT_HAS_${runtime_uppercase}) + add_subdirectory(${runtime}) + foreach(directory ${ARGN}) + add_subdirectory(${directory}) + endforeach() + endif() +endfunction() + # Run sanitizer tests only if we're sure that clang would produce # working binaries. if(COMPILER_RT_CAN_EXECUTE_TESTS) @@ -42,49 +52,24 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS) add_subdirectory(builtins) endif() if(COMPILER_RT_BUILD_SANITIZERS) - if(COMPILER_RT_HAS_ASAN) - add_subdirectory(asan) - endif() - if(COMPILER_RT_HAS_DFSAN) - add_subdirectory(dfsan) - endif() - if (COMPILER_RT_HAS_INTERCEPTION) - add_subdirectory(interception) - endif() - if(COMPILER_RT_HAS_LSAN) - add_subdirectory(lsan) - endif() - if(COMPILER_RT_HAS_MSAN) - add_subdirectory(msan) - endif() - if(COMPILER_RT_HAS_PROFILE) - add_subdirectory(profile) - endif() - if(COMPILER_RT_HAS_SANITIZER_COMMON) - add_subdirectory(sanitizer_common) - endif() - if(COMPILER_RT_HAS_TSAN) - add_subdirectory(tsan) - endif() - if(COMPILER_RT_HAS_UBSAN) - add_subdirectory(ubsan) - endif() + compiler_rt_test_runtime(interception) + + compiler_rt_test_runtime(lsan) # CFI tests require diagnostic mode, which is implemented in UBSan. - if(COMPILER_RT_HAS_UBSAN) - add_subdirectory(cfi) - endif() - if(COMPILER_RT_HAS_SAFESTACK) - add_subdirectory(safestack) - endif() - if(COMPILER_RT_HAS_ESAN) - add_subdirectory(esan) - endif() - if(COMPILER_RT_HAS_SCUDO) - add_subdirectory(scudo) - endif() + compiler_rt_test_runtime(ubsan cfi) + compiler_rt_test_runtime(sanitizer_common) + + foreach(sanitizer ${COMPILER_RT_SANITIZERS_TO_BUILD}) + # cfi testing is gated on ubsan + if(NOT ${sanitizer} STREQUAL cfi) + compiler_rt_test_runtime(${sanitizer}) + endif() + endforeach() + + compiler_rt_test_runtime(profile) endif() - if(COMPILER_RT_BUILD_XRAY AND COMPILER_RT_HAS_XRAY) - add_subdirectory(xray) + if(COMPILER_RT_BUILD_XRAY) + compiler_rt_test_runtime(xray) endif() endif() diff --git a/test/asan/TestCases/Darwin/asan_gen_prefixes.cc b/test/asan/TestCases/Darwin/asan_gen_prefixes.cc index 13363ac47255..9f3a66a7a708 100644 --- a/test/asan/TestCases/Darwin/asan_gen_prefixes.cc +++ b/test/asan/TestCases/Darwin/asan_gen_prefixes.cc @@ -4,6 +4,8 @@ // RUN: %clang_asan %s -S -o %t.s // RUN: cat %t.s | FileCheck %s || exit 1 +// UNSUPPORTED: ios + int x, y, z; int main() { return 0; } // CHECK: .section{{.*}}__TEXT,__const diff --git a/test/asan/TestCases/Darwin/nil-return-struct.mm b/test/asan/TestCases/Darwin/nil-return-struct.mm new file mode 100644 index 000000000000..9fb77e746339 --- /dev/null +++ b/test/asan/TestCases/Darwin/nil-return-struct.mm @@ -0,0 +1,31 @@ +// RUN: %clang_asan %s -o %t -framework Foundation +// RUN: %run %t 2>&1 | FileCheck %s + +#import <Foundation/Foundation.h> + +struct MyStruct { + long a, b, c, d; +}; + +@interface MyClass: NSObject +- (MyStruct)methodWhichReturnsARect; +@end +@implementation MyClass +- (MyStruct)methodWhichReturnsARect { + MyStruct s; + s.a = 10; + s.b = 20; + s.c = 30; + s.d = 40; + return s; +} +@end + +int main() { + MyClass *myNil = nil; // intentionally nil + [myNil methodWhichReturnsARect]; + fprintf(stderr, "Hello world"); +} + +// CHECK-NOT: AddressSanitizer: stack-use-after-scope +// CHECK: Hello world diff --git a/test/asan/TestCases/Linux/allocator_oom_test.cc b/test/asan/TestCases/Linux/allocator_oom_test.cc index 4c696f325803..33b6677de7d6 100644 --- a/test/asan/TestCases/Linux/allocator_oom_test.cc +++ b/test/asan/TestCases/Linux/allocator_oom_test.cc @@ -29,7 +29,8 @@ // RUN: | FileCheck %s --check-prefixes=CHECK-MALLOC-REALLOC,CHECK-NULL // ASan shadow memory on s390 is too large for this test. -// UNSUPPORTED: s390 +// TODO(alekseys): Android lit do not run ulimit on device. +// UNSUPPORTED: s390,android #include <stdlib.h> #include <string.h> diff --git a/test/asan/TestCases/Linux/asan_preload_test-3.cc b/test/asan/TestCases/Linux/asan_preload_test-3.cc index 041669b56a45..e998ff647b20 100644 --- a/test/asan/TestCases/Linux/asan_preload_test-3.cc +++ b/test/asan/TestCases/Linux/asan_preload_test-3.cc @@ -10,6 +10,9 @@ // RUN: env LD_PRELOAD=%shared_libasan %run %t-2 2>&1 | FileCheck %s // REQUIRES: asan-dynamic-runtime +// FIXME: Test regressed while android bot was disabled. Needs investigation. +// UNSUPPORTED: android + #include <stdlib.h> #include <stdio.h> diff --git a/test/asan/TestCases/Linux/init_fini_sections.cc b/test/asan/TestCases/Linux/init_fini_sections.cc index c7234eeeac2c..3037b232926e 100644 --- a/test/asan/TestCases/Linux/init_fini_sections.cc +++ b/test/asan/TestCases/Linux/init_fini_sections.cc @@ -2,11 +2,18 @@ #include <stdio.h> +int c = 0; + static void foo() { - printf("foo\n"); + ++c; +} + +static void fini() { + printf("fini\n"); } int main() { + printf("c=%d\n", c); return 0; } @@ -17,8 +24,7 @@ __attribute__((section(".init_array"))) void (*call_foo_2)(void) = &foo; __attribute__((section(".fini_array"))) -void (*call_foo_3)(void) = &foo; +void (*call_foo_3)(void) = &fini; -// CHECK: foo -// CHECK: foo -// CHECK: foo +// CHECK: c=2 +// CHECK: fini diff --git a/test/asan/TestCases/Linux/textdomain.c b/test/asan/TestCases/Linux/textdomain.c index 31e5139c9f7c..9e249d95ce67 100644 --- a/test/asan/TestCases/Linux/textdomain.c +++ b/test/asan/TestCases/Linux/textdomain.c @@ -1,6 +1,9 @@ // RUN: %clang_asan -O0 -g %s -o %t // RUN: %env_asan_opts=strict_string_checks=1 %run %t +// Android NDK does not have libintl.h +// UNSUPPORTED: android + #include <stdlib.h> #include <libintl.h> diff --git a/test/asan/TestCases/Posix/asan-sigbus.cpp b/test/asan/TestCases/Posix/asan-sigbus.cpp index d02ebbd9d8b0..c91ecbd756f6 100644 --- a/test/asan/TestCases/Posix/asan-sigbus.cpp +++ b/test/asan/TestCases/Posix/asan-sigbus.cpp @@ -1,8 +1,8 @@ // Check handle_bus flag // Defaults to true // RUN: %clangxx_asan -std=c++11 %s -o %t -// RUN: not %run %t %T/file 2>&1 | FileCheck %s -check-prefix=CHECK-BUS -// RUN: %env_asan_opts=handle_sigbus=0 not --crash %run %t %T/file 2>&1 | FileCheck %s +// RUN: not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-BUS +// RUN: %env_asan_opts=handle_sigbus=0 not --crash %run %t 2>&1 | FileCheck %s // UNSUPPORTED: ios @@ -12,11 +12,11 @@ #include <stdlib.h> #include <sys/mman.h> #include <unistd.h> +#include <string> char array[4096]; int main(int argc, char **argv) { - assert(argc > 1); - int fd = open(argv[1], O_RDWR | O_CREAT, 0700); + int fd = open((std::string(argv[0]) + ".m").c_str(), O_RDWR | O_CREAT, 0700); if (fd < 0) { perror("open"); exit(1); diff --git a/test/asan/TestCases/allocator_returns_null.cc b/test/asan/TestCases/allocator_returns_null.cc index cdfcd90c96cb..90e25b55e727 100644 --- a/test/asan/TestCases/allocator_returns_null.cc +++ b/test/asan/TestCases/allocator_returns_null.cc @@ -1,68 +1,97 @@ -// Test the behavior of malloc/calloc/realloc when the allocation size is huge. +// 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. +// 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 | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mNULL -// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cNULL -// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coNULL -// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rNULL -// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrCRASH -// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrNULL +// 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 +// 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 -#include <limits.h> -#include <stdlib.h> +#include <assert.h> #include <string.h> #include <stdio.h> -#include <assert.h> +#include <stdlib.h> #include <limits> +#include <new> + int main(int argc, char **argv) { // Disable stderr buffering. Needed on Windows. setvbuf(stderr, NULL, _IONBF, 0); - volatile size_t size = std::numeric_limits<size_t>::max() - 10000; assert(argc == 2); - void *x = 0; - if (!strcmp(argv[1], "malloc")) { - fprintf(stderr, "malloc:\n"); - x = malloc(size); - } - if (!strcmp(argv[1], "calloc")) { - fprintf(stderr, "calloc:\n"); - x = calloc(size / 4, 4); - } + const char *action = argv[1]; + fprintf(stderr, "%s:\n", action); - if (!strcmp(argv[1], "calloc-overflow")) { - fprintf(stderr, "calloc-overflow:\n"); + 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<size_t>::max(); size_t kArraySize = 4096; volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; x = calloc(kArraySize, kArraySize2); - } - - if (!strcmp(argv[1], "realloc")) { - fprintf(stderr, "realloc:\n"); - x = realloc(0, size); - } - if (!strcmp(argv[1], "realloc-after-malloc")) { - fprintf(stderr, "realloc-after-malloc:\n"); + } 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, size); + 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); } + // 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: AddressSanitizer's allocator is terminating the process // CHECK-cCRASH: calloc: @@ -73,6 +102,10 @@ int main(int argc, char **argv) { // CHECK-rCRASH: AddressSanitizer's allocator is terminating the process // CHECK-mrCRASH: realloc-after-malloc: // CHECK-mrCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-nCRASH: new: +// CHECK-nCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-nnCRASH: new-nothrow: +// CHECK-nnCRASH: AddressSanitizer's allocator is terminating the process // CHECK-mNULL: malloc: // CHECK-mNULL: x: 0 @@ -84,3 +117,5 @@ int main(int argc, char **argv) { // CHECK-rNULL: x: 0 // CHECK-mrNULL: realloc-after-malloc: // CHECK-mrNULL: x: 0 +// CHECK-nnNULL: new-nothrow: +// CHECK-nnNULL: x: 0 diff --git a/test/asan/TestCases/malloc-no-intercept.c b/test/asan/TestCases/malloc-no-intercept.c index 563f2ab15691..c1442e6cfa90 100644 --- a/test/asan/TestCases/malloc-no-intercept.c +++ b/test/asan/TestCases/malloc-no-intercept.c @@ -7,6 +7,9 @@ // RUN: not %clang_asan -Dtestfunc=pvalloc %s -o %t // RUN: not %clang_asan -Dtestfunc=cfree %s -o %t +// Conflicts with BIONIC declarations. +// UNSUPPORTED: android + #include <stdlib.h> // For glibc, cause link failures by referencing a nonexistent function. diff --git a/test/asan/TestCases/throw_call_test.cc b/test/asan/TestCases/throw_call_test.cc index 5a8204a04a54..20a7c0b76601 100644 --- a/test/asan/TestCases/throw_call_test.cc +++ b/test/asan/TestCases/throw_call_test.cc @@ -1,9 +1,6 @@ // RUN: %clangxx_asan %s -o %t && %run %t // http://code.google.com/p/address-sanitizer/issues/detail?id=147 (not fixed). // BROKEN: %clangxx_asan %s -o %t -static-libstdc++ && %run %t -// -// Android builds with static libstdc++ by default. -// XFAIL: android #include <stdio.h> static volatile int zero = 0; diff --git a/test/asan/android_commands/android_common.py b/test/asan/android_commands/android_common.py index 1a295b7817aa..41994bb87a14 100644 --- a/test/asan/android_commands/android_common.py +++ b/test/asan/android_commands/android_common.py @@ -37,8 +37,5 @@ def pull_from_device(path): return text def push_to_device(path): - # Workaround for https://code.google.com/p/android/issues/detail?id=65857 dst_path = os.path.join(ANDROID_TMPDIR, os.path.basename(path)) - tmp_path = dst_path + '.push' - adb(['push', path, tmp_path], 5) - adb(['shell', 'cp "%s" "%s" 2>&1' % (tmp_path, dst_path)], 5) + adb(['push', path, dst_path], 5) diff --git a/test/builtins/Unit/fp_test.h b/test/builtins/Unit/fp_test.h index 1f0e7be6d6a4..781b7e2c7d7d 100644 --- a/test/builtins/Unit/fp_test.h +++ b/test/builtins/Unit/fp_test.h @@ -85,7 +85,7 @@ static inline int compareResultH(uint16_t result, if (rep == expected){ return 0; } - // test other posible NaN representation(signal NaN) + // test other possible NaN representation(signal NaN) else if (expected == 0x7e00U){ if ((rep & 0x7c00U) == 0x7c00U && (rep & 0x3ffU) > 0){ @@ -103,7 +103,7 @@ static inline int compareResultF(float result, if (rep == expected){ return 0; } - // test other posible NaN representation(signal NaN) + // test other possible NaN representation(signal NaN) else if (expected == 0x7fc00000U){ if ((rep & 0x7f800000U) == 0x7f800000U && (rep & 0x7fffffU) > 0){ @@ -121,7 +121,7 @@ static inline int compareResultD(double result, if (rep == expected){ return 0; } - // test other posible NaN representation(signal NaN) + // test other possible NaN representation(signal NaN) else if (expected == 0x7ff8000000000000UL){ if ((rep & 0x7ff0000000000000UL) == 0x7ff0000000000000UL && (rep & 0xfffffffffffffUL) > 0){ @@ -146,7 +146,7 @@ static inline int compareResultLD(long double result, if (hi == expectedHi && lo == expectedLo){ return 0; } - // test other posible NaN representation(signal NaN) + // test other possible NaN representation(signal NaN) else if (expectedHi == 0x7fff800000000000UL && expectedLo == 0x0UL){ if ((hi & 0x7fff000000000000UL) == 0x7fff000000000000UL && ((hi & 0xffffffffffffUL) > 0 || lo > 0)){ diff --git a/test/cfi/sibling.cpp b/test/cfi/sibling.cpp index 9f32302ed5e6..601359888df0 100644 --- a/test/cfi/sibling.cpp +++ b/test/cfi/sibling.cpp @@ -15,7 +15,7 @@ // RUN: %clangxx -o %t5 %s // RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s -// Tests that the CFI enforcement distinguishes betwen non-overriding siblings. +// Tests that the CFI enforcement distinguishes between non-overriding siblings. // XFAILed as not implemented yet. #include <stdio.h> diff --git a/test/lsan/TestCases/allocator_returns_null.cc b/test/lsan/TestCases/allocator_returns_null.cc new file mode 100644 index 000000000000..ab2c734e1e58 --- /dev/null +++ b/test/lsan/TestCases/allocator_returns_null.cc @@ -0,0 +1,123 @@ +// 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 +// 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 <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <limits> +#include <new> + +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<size_t>::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); + } + + // 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: Sanitizer's allocator is terminating the process +// CHECK-cCRASH: calloc: +// CHECK-cCRASH: Sanitizer's allocator is terminating the process +// CHECK-coCRASH: calloc-overflow: +// CHECK-coCRASH: Sanitizer's allocator is terminating the process +// CHECK-rCRASH: realloc: +// CHECK-rCRASH: Sanitizer's allocator is terminating the process +// CHECK-mrCRASH: realloc-after-malloc: +// CHECK-mrCRASH: Sanitizer's allocator is terminating the process +// CHECK-nCRASH: new: +// CHECK-nCRASH: Sanitizer's allocator is terminating the process +// CHECK-nnCRASH: new-nothrow: +// CHECK-nnCRASH: Sanitizer's allocator is terminating the process + +// CHECK-mNULL: malloc: +// CHECK-mNULL: x: 0 +// CHECK-cNULL: calloc: +// CHECK-cNULL: x: 0 +// CHECK-coNULL: calloc-overflow: +// CHECK-coNULL: x: 0 +// CHECK-rNULL: realloc: +// CHECK-rNULL: x: 0 +// CHECK-mrNULL: realloc-after-malloc: +// CHECK-mrNULL: x: 0 +// CHECK-nnNULL: new-nothrow: +// CHECK-nnNULL: x: 0 diff --git a/test/msan/allocator_returns_null.cc b/test/msan/allocator_returns_null.cc index f4ea51d58872..2c7c32d404fc 100644 --- a/test/msan/allocator_returns_null.cc +++ b/test/msan/allocator_returns_null.cc @@ -1,63 +1,98 @@ -// Test the behavior of malloc/calloc/realloc when the allocation size is huge. +// 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. +// 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 | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mNULL -// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cNULL -// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coNULL -// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rNULL -// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrCRASH -// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrNULL +// 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 +// 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 -#include <limits.h> -#include <stdlib.h> + +#include <assert.h> #include <string.h> #include <stdio.h> -#include <assert.h> +#include <stdlib.h> #include <limits> +#include <new> + int main(int argc, char **argv) { - volatile size_t size = std::numeric_limits<size_t>::max() - 10000; + // Disable stderr buffering. Needed on Windows. + setvbuf(stderr, NULL, _IONBF, 0); + assert(argc == 2); - char *x = 0; - if (!strcmp(argv[1], "malloc")) { - fprintf(stderr, "malloc:\n"); - x = (char*)malloc(size); - } - if (!strcmp(argv[1], "calloc")) { - fprintf(stderr, "calloc:\n"); - x = (char*)calloc(size / 4, 4); - } + 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 - if (!strcmp(argv[1], "calloc-overflow")) { - fprintf(stderr, "calloc-overflow:\n"); + 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<size_t>::max(); size_t kArraySize = 4096; volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; - x = (char*)calloc(kArraySize, kArraySize2); - } - - if (!strcmp(argv[1], "realloc")) { - fprintf(stderr, "realloc:\n"); - x = (char*)realloc(0, size); - } - if (!strcmp(argv[1], "realloc-after-malloc")) { - fprintf(stderr, "realloc-after-malloc:\n"); + 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 = (char*)realloc(t, size); + 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); } + // 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: MemorySanitizer's allocator is terminating the process // CHECK-cCRASH: calloc: @@ -68,6 +103,10 @@ int main(int argc, char **argv) { // CHECK-rCRASH: MemorySanitizer's allocator is terminating the process // CHECK-mrCRASH: realloc-after-malloc: // CHECK-mrCRASH: MemorySanitizer's allocator is terminating the process +// CHECK-nCRASH: new: +// CHECK-nCRASH: MemorySanitizer's allocator is terminating the process +// CHECK-nnCRASH: new-nothrow: +// CHECK-nnCRASH: MemorySanitizer's allocator is terminating the process // CHECK-mNULL: malloc: // CHECK-mNULL: x: 0 @@ -79,3 +118,5 @@ int main(int argc, char **argv) { // CHECK-rNULL: x: 0 // CHECK-mrNULL: realloc-after-malloc: // CHECK-mrNULL: x: 0 +// CHECK-nnNULL: new-nothrow: +// CHECK-nnNULL: x: 0 diff --git a/test/profile/instrprof-override-filename.c b/test/profile/instrprof-override-filename.c index a67c7076afb5..d2b6b69a7003 100644 --- a/test/profile/instrprof-override-filename.c +++ b/test/profile/instrprof-override-filename.c @@ -1,14 +1,24 @@ -// RUN: %clang_profgen=%t.profraw -o %t -O3 %s -// RUN: %run %t %t.profraw -// RUN: llvm-profdata merge -o %t.profdata %t.profraw -// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s +// RUN: rm -rf %t.dir && mkdir -p %t.dir +// RUN: cd %t.dir +// +// RUN: %clang_profgen=P_RAW -o %t -O3 %s +// RUN: %run %t P_RAW +// RUN: llvm-profdata merge -o %t.profdata P_RAW +// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s --check-prefix=FE +// +// RUN: %clang_pgogen=I_RAW -o %t.2 %s +// RUN: %run %t.2 I_RAW +// RUN: llvm-profdata merge -o %t2.profdata I_RAW +// RUN: %clang_profuse=%t2.profdata -o - -S -emit-llvm %s | FileCheck %s --check-prefix=IR void bar() {} int main(int argc, const char *argv[]) { - // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]] + // FE: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]] + // IR: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]] if (argc < 2) return 1; bar(); return 0; } -// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2} +// FE: ![[PD1]] = !{!"branch_weights", i32 1, i32 2} +// IR: ![[PD1]] = !{!"branch_weights", i32 0, i32 1} diff --git a/test/scudo/memalign.cpp b/test/scudo/memalign.cpp index c263da75e616..856128f2489f 100644 --- a/test/scudo/memalign.cpp +++ b/test/scudo/memalign.cpp @@ -1,11 +1,12 @@ // RUN: %clang_scudo %s -o %t -// RUN: %run %t valid 2>&1 -// RUN: not %run %t invalid 2>&1 | FileCheck %s +// RUN: %run %t valid 2>&1 +// RUN: %run %t invalid 2>&1 // Tests that the various aligned allocation functions work as intended. Also // tests for the condition where the alignment is not a power of 2. #include <assert.h> +#include <errno.h> #include <malloc.h> #include <stdlib.h> #include <string.h> @@ -24,6 +25,7 @@ int main(int argc, char **argv) void *p = nullptr; size_t alignment = 1U << 12; size_t size = 1U << 12; + int err; assert(argc == 2); @@ -57,10 +59,22 @@ int main(int argc, char **argv) } } if (!strcmp(argv[1], "invalid")) { + // Alignment is not a power of 2. p = memalign(alignment - 1, size); - free(p); + assert(!p); + // Size is not a multiple of alignment. + p = aligned_alloc(alignment, size >> 1); + assert(!p); + p = (void *)0x42UL; + // Alignment is not a power of 2. + err = posix_memalign(&p, 3, size); + assert(!p); + assert(err == EINVAL); + p = (void *)0x42UL; + // Alignment is a power of 2, but not a multiple of size(void *). + err = posix_memalign(&p, 2, size); + assert(!p); + assert(err == EINVAL); } return 0; } - -// CHECK: ERROR: alignment is not a power of 2 diff --git a/test/scudo/sizes.cpp b/test/scudo/sizes.cpp index 981b859a8757..a0994c2515a2 100644 --- a/test/scudo/sizes.cpp +++ b/test/scudo/sizes.cpp @@ -1,8 +1,12 @@ -// RUN: %clang_scudo %s -o %t +// RUN: %clang_scudo %s -lstdc++ -o %t // RUN: SCUDO_OPTIONS=allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s // RUN: SCUDO_OPTIONS=allocator_may_return_null=1 %run %t malloc 2>&1 // RUN: SCUDO_OPTIONS=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s // RUN: SCUDO_OPTIONS=allocator_may_return_null=1 %run %t calloc 2>&1 +// RUN: SCUDO_OPTIONS=allocator_may_return_null=0 not %run %t new 2>&1 | FileCheck %s +// RUN: SCUDO_OPTIONS=allocator_may_return_null=1 not %run %t new 2>&1 | FileCheck %s +// RUN: SCUDO_OPTIONS=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 | FileCheck %s +// RUN: SCUDO_OPTIONS=allocator_may_return_null=1 %run %t new-nothrow 2>&1 // RUN: %run %t usable 2>&1 // Tests for various edge cases related to sizes, notably the maximum size the @@ -15,26 +19,38 @@ #include <string.h> #include <limits> +#include <new> -int main(int argc, char **argv) -{ +int main(int argc, char **argv) { assert(argc == 2); - if (!strcmp(argv[1], "malloc")) { - // Currently the maximum size the allocator can allocate is 1ULL<<40 bytes. - size_t size = std::numeric_limits<size_t>::max(); - void *p = malloc(size); + const char *action = argv[1]; + fprintf(stderr, "%s:\n", action); + +#if __LP64__ || defined(_WIN64) + static const size_t kMaxAllowedMallocSize = 1ULL << 40; + static const size_t kChunkHeaderSize = 16; +#else + static const size_t kMaxAllowedMallocSize = 2UL << 30; + static const size_t kChunkHeaderSize = 8; +#endif + + if (!strcmp(action, "malloc")) { + void *p = malloc(kMaxAllowedMallocSize); assert(!p); - size = (1ULL << 40) - 16; - p = malloc(size); + p = malloc(kMaxAllowedMallocSize - kChunkHeaderSize); assert(!p); - } - if (!strcmp(argv[1], "calloc")) { + } else if (!strcmp(action, "calloc")) { // Trigger an overflow in calloc. size_t size = std::numeric_limits<size_t>::max(); void *p = calloc((size / 0x1000) + 1, 0x1000); assert(!p); - } - if (!strcmp(argv[1], "usable")) { + } else if (!strcmp(action, "new")) { + void *p = operator new(kMaxAllowedMallocSize); + assert(!p); + } else if (!strcmp(action, "new-nothrow")) { + void *p = operator new(kMaxAllowedMallocSize, std::nothrow); + assert(!p); + } else if (!strcmp(action, "usable")) { // Playing with the actual usable size of a chunk. void *p = malloc(1007); assert(p); @@ -47,7 +63,10 @@ int main(int argc, char **argv) assert(size >= 2014); memset(p, 'B', size); free(p); + } else { + assert(0); } + return 0; } diff --git a/test/tsan/allocator_returns_null.cc b/test/tsan/allocator_returns_null.cc index 66930076ac3a..852dda035f23 100644 --- a/test/tsan/allocator_returns_null.cc +++ b/test/tsan/allocator_returns_null.cc @@ -1,56 +1,90 @@ -// Test the behavior of malloc/calloc/realloc when the allocation size is huge. +// Test the behavior of malloc/calloc/realloc/new when the allocation size is +// more than TSan 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. +// 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_tsan -O0 %s -o %t // RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cCRASH -// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coCRASH -// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rCRASH -// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrCRASH +// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-mCRASH +// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-mNULL +// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-cCRASH +// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t calloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-cNULL +// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-coCRASH +// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-coNULL +// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-rCRASH +// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t realloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-rNULL +// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-mrCRASH +// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-mrNULL +// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t new 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH +// RUN: %env_tsan_opts=allocator_may_return_null=1 not %run %t new 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH +// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH +// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-nnNULL -#include <limits.h> -#include <stdlib.h> +#include <assert.h> #include <string.h> #include <stdio.h> -#include <assert.h> +#include <stdlib.h> #include <limits> +#include <new> + int main(int argc, char **argv) { - volatile size_t size = std::numeric_limits<size_t>::max() - 10000; + // Disable stderr buffering. Needed on Windows. + setvbuf(stderr, NULL, _IONBF, 0); + assert(argc == 2); - char *x = 0; - if (!strcmp(argv[1], "malloc")) { - fprintf(stderr, "malloc:\n"); - x = (char*)malloc(size); - } - if (!strcmp(argv[1], "calloc")) { - fprintf(stderr, "calloc:\n"); - x = (char*)calloc(size / 4, 4); - } + const char *action = argv[1]; + fprintf(stderr, "%s:\n", action); + + static const size_t kMaxAllowedMallocSizePlusOne = (1ULL << 40) + 1; - if (!strcmp(argv[1], "calloc-overflow")) { - fprintf(stderr, "calloc-overflow:\n"); + 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<size_t>::max(); size_t kArraySize = 4096; volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; - x = (char*)calloc(kArraySize, kArraySize2); - } - - if (!strcmp(argv[1], "realloc")) { - fprintf(stderr, "realloc:\n"); - x = (char*)realloc(0, size); - } - if (!strcmp(argv[1], "realloc-after-malloc")) { - fprintf(stderr, "realloc-after-malloc:\n"); + 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 = (char*)realloc(t, size); + x = realloc(t, kMaxAllowedMallocSizePlusOne); assert(*t == 42); + } 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, "x: %p\n", x); + + // 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: ThreadSanitizer's allocator is terminating the process // CHECK-cCRASH: calloc: @@ -61,4 +95,20 @@ int main(int argc, char **argv) { // CHECK-rCRASH: ThreadSanitizer's allocator is terminating the process // CHECK-mrCRASH: realloc-after-malloc: // CHECK-mrCRASH: ThreadSanitizer's allocator is terminating the process +// CHECK-nCRASH: new: +// CHECK-nCRASH: ThreadSanitizer's allocator is terminating the process +// CHECK-nnCRASH: new-nothrow: +// CHECK-nnCRASH: ThreadSanitizer's allocator is terminating the process +// CHECK-mNULL: malloc: +// CHECK-mNULL: x: 0 +// CHECK-cNULL: calloc: +// CHECK-cNULL: x: 0 +// CHECK-coNULL: calloc-overflow: +// CHECK-coNULL: x: 0 +// CHECK-rNULL: realloc: +// CHECK-rNULL: x: 0 +// CHECK-mrNULL: realloc-after-malloc: +// CHECK-mrNULL: x: 0 +// CHECK-nnNULL: new-nothrow: +// CHECK-nnNULL: x: 0 diff --git a/test/xray/TestCases/Linux/always-never-instrument.cc b/test/xray/TestCases/Linux/always-never-instrument.cc new file mode 100644 index 000000000000..4e196859bcda --- /dev/null +++ b/test/xray/TestCases/Linux/always-never-instrument.cc @@ -0,0 +1,23 @@ +// Test that the always/never instrument lists apply. +// RUN: echo "fun:main" > %tmp-always.txt +// RUN: echo "fun:__xray*" > %tmp-never.txt +// RUN: %clangxx_xray \ +// RUN: -fxray-never-instrument=%tmp-never.txt \ +// RUN: -fxray-always-instrument=%tmp-always.txt \ +// RUN: %s -o %t +// RUN: %llvm_xray extract -symbolize %t | \ +// RUN: FileCheck %s --check-prefix NOINSTR +// RUN: %llvm_xray extract -symbolize %t | \ +// RUN: FileCheck %s --check-prefix ALWAYSINSTR +// REQUIRES: x86_64-linux +// REQUIRES: built-in-llvm-tree + +// NOINSTR-NOT: {{.*__xray_NeverInstrumented.*}} +int __xray_NeverInstrumented() { + return 0; +} + +// ALWAYSINSTR: {{.*function-name:.*main.*}} +int main(int argc, char *argv[]) { + return __xray_NeverInstrumented(); +} |