diff options
Diffstat (limited to 'test/ubsan/TestCases/Misc')
-rw-r--r-- | test/ubsan/TestCases/Misc/bool.cpp | 10 | ||||
-rw-r--r-- | test/ubsan/TestCases/Misc/bounds.cpp | 15 | ||||
-rw-r--r-- | test/ubsan/TestCases/Misc/deduplication.cpp | 25 | ||||
-rw-r--r-- | test/ubsan/TestCases/Misc/enum.cpp | 17 | ||||
-rw-r--r-- | test/ubsan/TestCases/Misc/missing_return.cpp | 17 | ||||
-rw-r--r-- | test/ubsan/TestCases/Misc/nonnull-arg.cpp | 58 | ||||
-rw-r--r-- | test/ubsan/TestCases/Misc/nonnull.cpp | 15 | ||||
-rw-r--r-- | test/ubsan/TestCases/Misc/unreachable.cpp | 6 | ||||
-rw-r--r-- | test/ubsan/TestCases/Misc/vla.c | 11 |
9 files changed, 174 insertions, 0 deletions
diff --git a/test/ubsan/TestCases/Misc/bool.cpp b/test/ubsan/TestCases/Misc/bool.cpp new file mode 100644 index 0000000000000..37ecea27c9411 --- /dev/null +++ b/test/ubsan/TestCases/Misc/bool.cpp @@ -0,0 +1,10 @@ +// RUN: %clangxx -fsanitize=bool %s -O3 -o %t && not %run %t 2>&1 | FileCheck %s + +unsigned char NotABool = 123; + +int main(int argc, char **argv) { + bool *p = (bool*)&NotABool; + + // CHECK: bool.cpp:9:10: runtime error: load of value 123, which is not a valid value for type 'bool' + return *p; +} diff --git a/test/ubsan/TestCases/Misc/bounds.cpp b/test/ubsan/TestCases/Misc/bounds.cpp new file mode 100644 index 0000000000000..ffcac528be904 --- /dev/null +++ b/test/ubsan/TestCases/Misc/bounds.cpp @@ -0,0 +1,15 @@ +// RUN: %clangxx -fsanitize=bounds %s -O3 -o %t +// RUN: %run %t 0 0 0 +// RUN: %run %t 1 2 3 +// RUN: not --crash %run %t 2 0 0 2>&1 | FileCheck %s --check-prefix=CHECK-A-2 +// RUN: %run %t 0 3 0 2>&1 | FileCheck %s --check-prefix=CHECK-B-3 +// RUN: %run %t 0 0 4 2>&1 | FileCheck %s --check-prefix=CHECK-C-4 + +int main(int argc, char **argv) { + int arr[2][3][4] = {}; + + return arr[argv[1][0] - '0'][argv[2][0] - '0'][argv[3][0] - '0']; + // CHECK-A-2: bounds.cpp:[[@LINE-1]]:10: runtime error: index 2 out of bounds for type 'int [2][3][4]' + // CHECK-B-3: bounds.cpp:[[@LINE-2]]:10: runtime error: index 3 out of bounds for type 'int [3][4]' + // CHECK-C-4: bounds.cpp:[[@LINE-3]]:10: runtime error: index 4 out of bounds for type 'int [4]' +} diff --git a/test/ubsan/TestCases/Misc/deduplication.cpp b/test/ubsan/TestCases/Misc/deduplication.cpp new file mode 100644 index 0000000000000..7d7b0bd58c6ed --- /dev/null +++ b/test/ubsan/TestCases/Misc/deduplication.cpp @@ -0,0 +1,25 @@ +// RUN: %clangxx -fsanitize=undefined %s -o %t && %run %t 2>&1 | FileCheck %s +// Verify deduplication works by ensuring only one diag is emitted. +#include <limits.h> +#include <stdio.h> + +void overflow() { + int i = INT_MIN; + --i; +} + +int main() { + // CHECK: Start + fprintf(stderr, "Start\n"); + + // CHECK: runtime error + // CHECK-NOT: runtime error + // CHECK-NOT: runtime error + overflow(); + overflow(); + overflow(); + + // CHECK: End + fprintf(stderr, "End\n"); + return 0; +} diff --git a/test/ubsan/TestCases/Misc/enum.cpp b/test/ubsan/TestCases/Misc/enum.cpp new file mode 100644 index 0000000000000..49ac7c6bb1878 --- /dev/null +++ b/test/ubsan/TestCases/Misc/enum.cpp @@ -0,0 +1,17 @@ +// RUN: %clangxx -fsanitize=enum %s -O3 -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PLAIN +// RUN: %clangxx -fsanitize=enum -std=c++11 -DE="class E" %s -O3 -o %t && %run %t +// RUN: %clangxx -fsanitize=enum -std=c++11 -DE="class E : bool" %s -O3 -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-BOOL + +enum E { a = 1 } e; +#undef E + +int main(int argc, char **argv) { + // memset(&e, 0xff, sizeof(e)); + for (unsigned char *p = (unsigned char*)&e; p != (unsigned char*)(&e + 1); ++p) + *p = 0xff; + + // CHECK-PLAIN: error: load of value 4294967295, which is not a valid value for type 'enum E' + // FIXME: Support marshalling and display of enum class values. + // CHECK-BOOL: error: load of value <unknown>, which is not a valid value for type 'enum E' + return (int)e != -1; +} diff --git a/test/ubsan/TestCases/Misc/missing_return.cpp b/test/ubsan/TestCases/Misc/missing_return.cpp new file mode 100644 index 0000000000000..5d3d54de17ddc --- /dev/null +++ b/test/ubsan/TestCases/Misc/missing_return.cpp @@ -0,0 +1,17 @@ +// RUN: %clangxx -fsanitize=return -g %s -O3 -o %t +// RUN: not %run %t 2>&1 | FileCheck %s +// RUN: UBSAN_OPTIONS=print_stacktrace=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os-STACKTRACE + +// CHECK: missing_return.cpp:[[@LINE+1]]:5: runtime error: execution reached the end of a value-returning function without returning a value +int f() { +// Slow stack unwinding is disabled on Darwin for now, see +// https://code.google.com/p/address-sanitizer/issues/detail?id=137 +// CHECK-Linux-STACKTRACE: #0 {{.*}} in f(){{.*}}missing_return.cpp:[[@LINE-3]] +// CHECK-FreeBSD-STACKTRACE: #0 {{.*}} in f(void){{.*}}missing_return.cpp:[[@LINE-4]] +// Check for already checked line to avoid lit error reports. +// CHECK-Darwin-STACKTRACE: missing_return.cpp +} + +int main(int, char **argv) { + return f(); +} diff --git a/test/ubsan/TestCases/Misc/nonnull-arg.cpp b/test/ubsan/TestCases/Misc/nonnull-arg.cpp new file mode 100644 index 0000000000000..b1061b757899c --- /dev/null +++ b/test/ubsan/TestCases/Misc/nonnull-arg.cpp @@ -0,0 +1,58 @@ +// RUN: %clangxx -fsanitize=nonnull-attribute -fno-sanitize-recover %s -O3 -o %t +// RUN: %run %t nc +// RUN: %run %t nm +// RUN: %run %t nf +// RUN: %run %t nv +// RUN: not %run %t 0c 2>&1 | FileCheck %s --check-prefix=CTOR +// RUN: not %run %t 0m 2>&1 | FileCheck %s --check-prefix=METHOD +// RUN: not %run %t 0f 2>&1 | FileCheck %s --check-prefix=FUNC +// RUN: not %run %t 0v 2>&1 | FileCheck %s --check-prefix=VARIADIC + +class C { + int *null_; + int *nonnull_; + +public: + C(int *null, __attribute__((nonnull)) int *nonnull) + : null_(null), nonnull_(nonnull) {} + int value() { return *nonnull_; } + int method(int *nonnull, int *null) __attribute__((nonnull(2))) { + return *nonnull_ + *nonnull; + } +}; + +__attribute__((nonnull)) int func(int *nonnull) { return *nonnull; } + +#include <stdarg.h> +__attribute__((nonnull)) int variadic(int x, ...) { + va_list args; + va_start(args, x); + int *nonnull = va_arg(args, int*); + int res = *nonnull; + va_end(args); + return res; +} + +int main(int argc, char *argv[]) { + int local = 0; + int *arg = (argv[1][0] == '0') ? 0x0 : &local; + switch (argv[1][1]) { + case 'c': + return C(0x0, arg).value(); + // CTOR: {{.*}}nonnull-arg.cpp:[[@LINE-1]]:21: runtime error: null pointer passed as argument 2, which is declared to never be null + // CTOR-NEXT: {{.*}}nonnull-arg.cpp:16:31: note: nonnull attribute specified here + case 'm': + return C(0x0, &local).method(arg, 0x0); + // METHOD: {{.*}}nonnull-arg.cpp:[[@LINE-1]]:36: runtime error: null pointer passed as argument 1, which is declared to never be null + // METHOD-NEXT: {{.*}}nonnull-arg.cpp:19:54: note: nonnull attribute specified here + case 'f': + return func(arg); + // FUNC: {{.*}}nonnull-arg.cpp:[[@LINE-1]]:19: runtime error: null pointer passed as argument 1, which is declared to never be null + // FUNC-NEXT: {{.*}}nonnull-arg.cpp:24:16: note: nonnull attribute specified here + case 'v': + return variadic(42, arg); + // VARIADIC: {{.*}}nonnull-arg.cpp:[[@LINE-1]]:27: runtime error: null pointer passed as argument 2, which is declared to never be null + // VARIADIC-NEXT: {{.*}}nonnull-arg.cpp:27:16: note: nonnull attribute specified here + } + return 0; +} diff --git a/test/ubsan/TestCases/Misc/nonnull.cpp b/test/ubsan/TestCases/Misc/nonnull.cpp new file mode 100644 index 0000000000000..c3ab49c11df7b --- /dev/null +++ b/test/ubsan/TestCases/Misc/nonnull.cpp @@ -0,0 +1,15 @@ +// RUN: %clangxx -fsanitize=returns-nonnull-attribute %s -O3 -o %t +// RUN: %run %t foo +// RUN: %run %t 2>&1 | FileCheck %s + +__attribute__((returns_nonnull)) char *foo(char *a); + +char *foo(char *a) { + return a; + // CHECK: nonnull.cpp:[[@LINE+2]]:1: runtime error: null pointer returned from function declared to never return null + // CHECK-NEXT: nonnull.cpp:[[@LINE-5]]:16: note: returns_nonnull attribute specified here +} + +int main(int argc, char **argv) { + return foo(argv[1]) == 0; +} diff --git a/test/ubsan/TestCases/Misc/unreachable.cpp b/test/ubsan/TestCases/Misc/unreachable.cpp new file mode 100644 index 0000000000000..e1206edb30d54 --- /dev/null +++ b/test/ubsan/TestCases/Misc/unreachable.cpp @@ -0,0 +1,6 @@ +// RUN: %clangxx -fsanitize=unreachable %s -O3 -o %t && not %run %t 2>&1 | FileCheck %s + +int main(int, char **argv) { + // CHECK: unreachable.cpp:5:3: runtime error: execution reached a __builtin_unreachable() call + __builtin_unreachable(); +} diff --git a/test/ubsan/TestCases/Misc/vla.c b/test/ubsan/TestCases/Misc/vla.c new file mode 100644 index 0000000000000..10721537bbbc7 --- /dev/null +++ b/test/ubsan/TestCases/Misc/vla.c @@ -0,0 +1,11 @@ +// RUN: %clang -fsanitize=vla-bound %s -O3 -o %t +// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-MINUS-ONE +// RUN: %run %t a 2>&1 | FileCheck %s --check-prefix=CHECK-ZERO +// RUN: %run %t a b + +int main(int argc, char **argv) { + // CHECK-MINUS-ONE: vla.c:9:11: runtime error: variable length array bound evaluates to non-positive value -1 + // CHECK-ZERO: vla.c:9:11: runtime error: variable length array bound evaluates to non-positive value 0 + int arr[argc - 2]; + return 0; +} |