aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2012-12-04 01:34:23 +0000
committerAlexey Samsonov <samsonov@google.com>2012-12-04 01:34:23 +0000
commitf985f44b13681071e585acb7a5703a2c1c23b6ce (patch)
tree23b87f4841c89e7bb002b286417c7f8a09688361 /test
parentf94e8c4cafc6a2ce7ff5c0c46084d3c38c2921f6 (diff)
ASan: add initial support for handling llvm.lifetime intrinsics in ASan - emit calls into runtime library that poison memory for local variables when their lifetime is over and unpoison memory when their lifetime begins.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169200 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/Instrumentation/AddressSanitizer/lifetime.ll61
1 files changed, 61 insertions, 0 deletions
diff --git a/test/Instrumentation/AddressSanitizer/lifetime.ll b/test/Instrumentation/AddressSanitizer/lifetime.ll
new file mode 100644
index 0000000000..55cd475f1f
--- /dev/null
+++ b/test/Instrumentation/AddressSanitizer/lifetime.ll
@@ -0,0 +1,61 @@
+; Test hanlding of llvm.lifetime intrinsics.
+; RUN: opt < %s -asan -asan-check-lifetime -S | FileCheck %s
+
+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"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind
+declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind
+
+define void @lifetime_no_size() address_safety {
+entry:
+ %i = alloca i32, align 4
+ %i.ptr = bitcast i32* %i to i8*
+ call void @llvm.lifetime.start(i64 -1, i8* %i.ptr)
+ call void @llvm.lifetime.end(i64 -1, i8* %i.ptr)
+
+; Check that lifetime with no size are ignored.
+; CHECK: @lifetime_no_size
+; CHECK-NOT: @__asan_poison_stack_memory
+; CHECK-NOT: @__asan_unpoison_stack_memory
+; CHECK: ret void
+ ret void
+}
+
+; Generic case of lifetime analysis.
+define void @lifetime() address_safety {
+ ; CHECK: @lifetime
+
+ ; Regular variable lifetime intrinsics.
+ %i = alloca i32, align 4
+ %i.ptr = bitcast i32* %i to i8*
+ call void @llvm.lifetime.start(i64 3, i8* %i.ptr)
+ ; Memory is unpoisoned at llvm.lifetime.start
+ ; CHECK: %[[VAR:[^ ]*]] = ptrtoint i8* %i.ptr to i64
+ ; CHECK-NEXT: call void @__asan_unpoison_stack_memory(i64 %[[VAR]], i64 3)
+ call void @llvm.lifetime.end(i64 4, i8* %i.ptr)
+ call void @llvm.lifetime.end(i64 2, i8* %i.ptr)
+ ; Memory is poisoned at every call to llvm.lifetime.end
+ ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 4)
+ ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 2)
+
+ ; Lifetime intrinsics for array.
+ %arr = alloca [10 x i32], align 16
+ %arr.ptr = bitcast [10 x i32]* %arr to i8*
+ call void @llvm.lifetime.start(i64 40, i8* %arr.ptr)
+ ; CHECK: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 40)
+ call void @llvm.lifetime.end(i64 40, i8* %arr.ptr)
+ ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 40)
+
+ ; One more lifetime start/end for the same variable %i.
+ call void @llvm.lifetime.start(i64 4, i8* %i.ptr)
+ ; CHECK: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 4)
+ call void @llvm.lifetime.end(i64 4, i8* %i.ptr)
+ ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 4)
+
+ ; Memory is unpoisoned at function exit (only once).
+ ; CHECK: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 {{.*}})
+ ; CHECK-NOT: @__asan_unpoison_stack_memory
+ ; CHECK: ret void
+ ret void
+}