summaryrefslogtreecommitdiffstats
path: root/llvm/test/Instrumentation/ThreadSanitizer
diff options
context:
space:
mode:
authorKuba Brecka <kuba.brecka@gmail.com>2016-11-14 21:41:13 +0000
committerKuba Brecka <kuba.brecka@gmail.com>2016-11-14 21:41:13 +0000
commitddfdba3b01fa2ca9066feaf472feb78da1ca2cfc (patch)
treef7bd88d769015d7c3bc086588aae672210cb6e3c /llvm/test/Instrumentation/ThreadSanitizer
parent5375fe820cff7ae7f3c5c771f28c6f5518f2ee60 (diff)
downloadbcm5719-llvm-ddfdba3b01fa2ca9066feaf472feb78da1ca2cfc.tar.gz
bcm5719-llvm-ddfdba3b01fa2ca9066feaf472feb78da1ca2cfc.zip
[tsan] Add support for C++ exceptions into TSan (call __tsan_func_exit during unwinding), LLVM part
This adds support for TSan C++ exception handling, where we need to add extra calls to __tsan_func_exit when a function is exitted via exception mechanisms. Otherwise the shadow stack gets corrupted (leaked). This patch moves and enhances the existing implementation of EscapeEnumerator that finds all possible function exit points, and adds extra EH cleanup blocks where needed. Differential Revision: https://reviews.llvm.org/D26177 llvm-svn: 286893
Diffstat (limited to 'llvm/test/Instrumentation/ThreadSanitizer')
-rw-r--r--llvm/test/Instrumentation/ThreadSanitizer/eh.ll57
-rw-r--r--llvm/test/Instrumentation/ThreadSanitizer/no_sanitize_thread.ll2
-rw-r--r--llvm/test/Instrumentation/ThreadSanitizer/sanitize-thread-no-checking.ll2
-rw-r--r--llvm/test/Instrumentation/ThreadSanitizer/str-nobuiltin.ll14
4 files changed, 66 insertions, 9 deletions
diff --git a/llvm/test/Instrumentation/ThreadSanitizer/eh.ll b/llvm/test/Instrumentation/ThreadSanitizer/eh.ll
new file mode 100644
index 00000000000..a9a54b6cae2
--- /dev/null
+++ b/llvm/test/Instrumentation/ThreadSanitizer/eh.ll
@@ -0,0 +1,57 @@
+; RUN: opt < %s -tsan -S | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-EXC
+; RUN: opt < %s -tsan -S -tsan-handle-cxx-exceptions=0 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOEXC
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+
+declare void @can_throw()
+declare void @cannot_throw() nounwind
+
+define i32 @func1() sanitize_thread {
+ call void @can_throw()
+ ret i32 0
+ ; CHECK-EXC: define i32 @func1()
+ ; CHECK-EXC: call void @__tsan_func_entry
+ ; CHECK-EXC: invoke void @can_throw()
+ ; CHECK-EXC: .noexc:
+ ; CHECK-EXC: call void @__tsan_func_exit()
+ ; CHECK-EXC: ret i32 0
+ ; CHECK-EXC: tsan_cleanup:
+ ; CHECK-EXC: call void @__tsan_func_exit()
+ ; CHECK-EXC: resume
+ ; CHECK-NOEXC: define i32 @func1()
+ ; CHECK-NOEXC: call void @__tsan_func_entry
+ ; CHECK-NOEXC: call void @can_throw()
+ ; CHECK-NOEXC: call void @__tsan_func_exit()
+ ; CHECK-NOEXC: ret i32 0
+}
+
+define i32 @func2() sanitize_thread {
+ call void @cannot_throw()
+ ret i32 0
+ ; CHECK: define i32 @func2()
+ ; CHECK: call void @__tsan_func_entry
+ ; CHECK: call void @cannot_throw()
+ ; CHECK: call void @__tsan_func_exit()
+ ; CHECK: ret i32 0
+}
+
+define i32 @func3(i32* %p) sanitize_thread {
+ %a = load i32, i32* %p
+ ret i32 %a
+ ; CHECK: define i32 @func3(i32* %p)
+ ; CHECK: call void @__tsan_func_entry
+ ; CHECK: call void @__tsan_read4
+ ; CHECK: %a = load i32, i32* %p
+ ; CHECK: call void @__tsan_func_exit()
+ ; CHECK: ret i32 %a
+}
+
+define i32 @func4() sanitize_thread nounwind {
+ call void @can_throw()
+ ret i32 0
+ ; CHECK: define i32 @func4()
+ ; CHECK: call void @__tsan_func_entry
+ ; CHECK: call void @can_throw()
+ ; CHECK: call void @__tsan_func_exit()
+ ; CHECK: ret i32 0
+}
diff --git a/llvm/test/Instrumentation/ThreadSanitizer/no_sanitize_thread.ll b/llvm/test/Instrumentation/ThreadSanitizer/no_sanitize_thread.ll
index a90a56064a0..70154251d14 100644
--- a/llvm/test/Instrumentation/ThreadSanitizer/no_sanitize_thread.ll
+++ b/llvm/test/Instrumentation/ThreadSanitizer/no_sanitize_thread.ll
@@ -32,5 +32,5 @@ entry:
; CHECK-NEXT: call void @__tsan_func_exit()
; CHECK-NEXT: ret i32 %tmp1
-declare void @foo()
+declare void @foo() nounwind
diff --git a/llvm/test/Instrumentation/ThreadSanitizer/sanitize-thread-no-checking.ll b/llvm/test/Instrumentation/ThreadSanitizer/sanitize-thread-no-checking.ll
index 1bb3291f484..8bd45031f1d 100644
--- a/llvm/test/Instrumentation/ThreadSanitizer/sanitize-thread-no-checking.ll
+++ b/llvm/test/Instrumentation/ThreadSanitizer/sanitize-thread-no-checking.ll
@@ -14,7 +14,7 @@ entry:
; CHECK-NEXT: %tmp1 = load i32, i32* %a, align 4
; CHECK-NEXT: ret i32 %tmp1
-declare void @"foo"()
+declare void @"foo"() nounwind
define i32 @"\01-[WithCalls dealloc]"(i32* %a) "sanitize_thread_no_checking_at_run_time" {
entry:
diff --git a/llvm/test/Instrumentation/ThreadSanitizer/str-nobuiltin.ll b/llvm/test/Instrumentation/ThreadSanitizer/str-nobuiltin.ll
index 452d7becaaa..7f9383de404 100644
--- a/llvm/test/Instrumentation/ThreadSanitizer/str-nobuiltin.ll
+++ b/llvm/test/Instrumentation/ThreadSanitizer/str-nobuiltin.ll
@@ -4,13 +4,13 @@
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"
-declare i8* @memchr(i8* %a, i32 %b, i64 %c)
-declare i32 @memcmp(i8* %a, i8* %b, i64 %c)
-declare i32 @strcmp(i8* %a, i8* %b)
-declare i8* @strcpy(i8* %a, i8* %b)
-declare i8* @stpcpy(i8* %a, i8* %b)
-declare i64 @strlen(i8* %a)
-declare i64 @strnlen(i8* %a, i64 %b)
+declare i8* @memchr(i8* %a, i32 %b, i64 %c) nounwind
+declare i32 @memcmp(i8* %a, i8* %b, i64 %c) nounwind
+declare i32 @strcmp(i8* %a, i8* %b) nounwind
+declare i8* @strcpy(i8* %a, i8* %b) nounwind
+declare i8* @stpcpy(i8* %a, i8* %b) nounwind
+declare i64 @strlen(i8* %a) nounwind
+declare i64 @strnlen(i8* %a, i64 %b) nounwind
; CHECK: call{{.*}}@memchr{{.*}} #[[ATTR:[0-9]+]]
; CHECK: call{{.*}}@memcmp{{.*}} #[[ATTR]]
OpenPOWER on IntegriCloud