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