1; Test hanlding of llvm.lifetime intrinsics. 2; RUN: opt < %s -asan -asan-module -asan-use-after-scope -asan-use-after-return=0 -S | FileCheck %s 3; RUN: opt < %s -asan -asan-module -asan-use-after-scope -asan-use-after-return=0 -asan-instrument-allocas=0 -S | FileCheck %s --check-prefix=CHECK-NO-DYNAMIC 4 5target 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" 6target triple = "x86_64-unknown-linux-gnu" 7 8declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind 9declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind 10 11define void @lifetime_no_size() sanitize_address { 12entry: 13 %i = alloca i32, align 4 14 %i.ptr = bitcast i32* %i to i8* 15 call void @llvm.lifetime.start(i64 -1, i8* %i.ptr) 16 store volatile i8 0, i8* %i.ptr 17 call void @llvm.lifetime.end(i64 -1, i8* %i.ptr) 18 19; Check that lifetime with no size are ignored. 20; CHECK-LABEL: define void @lifetime_no_size() 21; CHECK-NOT: @__asan_poison_stack_memory 22; CHECK-NOT: @__asan_unpoison_stack_memory 23; CHECK: ret void 24 ret void 25} 26 27; Generic case of lifetime analysis. 28define void @lifetime() sanitize_address { 29 ; CHECK-LABEL: define void @lifetime() 30 31 ; Regular variable lifetime intrinsics. 32 %i = alloca i32, align 4 33 %i.ptr = bitcast i32* %i to i8* 34 call void @llvm.lifetime.start(i64 3, i8* %i.ptr) 35 store volatile i8 0, i8* %i.ptr 36 ; Memory is unpoisoned at llvm.lifetime.start 37 ; CHECK: %[[VAR:[^ ]*]] = ptrtoint i32* %{{[^ ]+}} to i64 38 ; CHECK-NEXT: call void @__asan_unpoison_stack_memory(i64 %[[VAR]], i64 3) 39 call void @llvm.lifetime.end(i64 4, i8* %i.ptr) 40 call void @llvm.lifetime.end(i64 2, i8* %i.ptr) 41 ; Memory is poisoned at every call to llvm.lifetime.end 42 ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 4) 43 ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 2) 44 45 ; Lifetime intrinsics for array. 46 %arr = alloca [10 x i32], align 16 47 %arr.ptr = bitcast [10 x i32]* %arr to i8* 48 call void @llvm.lifetime.start(i64 40, i8* %arr.ptr) 49 store volatile i8 0, i8* %arr.ptr 50 ; CHECK: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 40) 51 ; CHECK-NO-DYNAMIC-NOT: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 40) 52 call void @llvm.lifetime.end(i64 40, i8* %arr.ptr) 53 ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 40) 54 ; CHECK-NO-DYNAMIC-NOT: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 40) 55 56 ; One more lifetime start/end for the same variable %i. 57 call void @llvm.lifetime.start(i64 4, i8* %i.ptr) 58 store volatile i8 0, i8* %i.ptr 59 ; CHECK: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 4) 60 call void @llvm.lifetime.end(i64 4, i8* %i.ptr) 61 ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 4) 62 63 ; Memory is unpoisoned at function exit (only once). 64 ; CHECK: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 {{.*}}) 65 ; CHECK-NOT: @__asan_unpoison_stack_memory 66 ; CHECK: ret void 67 ret void 68} 69 70; Check that arguments of lifetime may come from phi nodes. 71define void @phi_args(i1 %x) sanitize_address { 72 ; CHECK-LABEL: define void @phi_args(i1 %x) 73 74entry: 75 %i = alloca i64, align 4 76 %i.ptr = bitcast i64* %i to i8* 77 call void @llvm.lifetime.start(i64 8, i8* %i.ptr) 78 store volatile i8 0, i8* %i.ptr 79 ; CHECK: __asan_unpoison_stack_memory 80 br i1 %x, label %bb0, label %bb1 81 82bb0: 83 %i.ptr2 = bitcast i64* %i to i8* 84 br label %bb1 85 86bb1: 87 %i.phi = phi i8* [ %i.ptr, %entry ], [ %i.ptr2, %bb0 ] 88 call void @llvm.lifetime.end(i64 8, i8* %i.phi) 89 ; CHECK: __asan_poison_stack_memory 90 ; CHECK: ret void 91 ret void 92} 93 94define void @zero_sized(i64 %a) #0 { 95; CHECK-LABEL: define void @zero_sized(i64 %a) 96 97entry: 98 %a.addr = alloca i64, align 8 99 %b = alloca [0 x i8], align 1 100 store i64 %a, i64* %a.addr, align 8 101 %0 = bitcast [0 x i8]* %b to i8* 102 call void @llvm.lifetime.start(i64 0, i8* %0) #2 103 ; CHECK-NOT: call void @__asan_unpoison_stack_memory 104 %1 = bitcast [0 x i8]* %b to i8* 105 call void @llvm.lifetime.end(i64 0, i8* %1) #2 106 ; CHECK-NOT: call void @__asan_poison_stack_memory 107 108 ret void 109} 110