Home | History | Annotate | Download | only in AddressSanitizer
      1 ; Test handling of llvm.lifetime intrinsics.
      2 ; RUN: opt < %s -asan -asan-module -asan-use-after-scope -asan-use-after-return=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK-DEFAULT
      3 ; RUN: opt < %s -asan -asan-module -asan-use-after-scope -asan-use-after-return=0 -asan-instrument-dynamic-allocas=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK-NO-DYNAMIC
      4 
      5 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"
      6 target triple = "x86_64-unknown-linux-gnu"
      7 
      8 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind
      9 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) nounwind
     10 
     11 define void @lifetime_no_size() sanitize_address {
     12   ; CHECK-LABEL: define void @lifetime_no_size()
     13 entry:
     14   %i = alloca i32, align 4
     15   %i.ptr = bitcast i32* %i to i8*
     16 
     17   ; Poison memory in prologue: F1F1F1F104F3F3F3
     18   ; CHECK: store i64 -868083100587789839, i64* %{{[0-9]+}}
     19 
     20   call void @llvm.lifetime.start.p0i8(i64 -1, i8* %i.ptr)
     21   ; Check that lifetime with no size are ignored.
     22   ; CHECK-NOT: store
     23   ; CHECK: call void @llvm.lifetime.start
     24 
     25   store volatile i8 0, i8* %i.ptr
     26   ; CHECK: store volatile
     27 
     28   call void @llvm.lifetime.end.p0i8(i64 -1, i8* %i.ptr)
     29   ; Check that lifetime with no size are ignored.
     30   ; CHECK-NOT: store
     31   ; CHECK: call void @llvm.lifetime.end
     32 
     33   ; Unpoison stack frame on exit.
     34   ; CHECK: store i64 0, i64* %{{[0-9]+}}
     35   ; CHECK: ret void
     36   ret void
     37 }
     38 
     39 ; Generic case of lifetime analysis.
     40 define void @lifetime() sanitize_address {
     41   ; CHECK-LABEL: define void @lifetime()
     42 
     43   ; Regular variable lifetime intrinsics.
     44   %i = alloca i32, align 4
     45   %i.ptr = bitcast i32* %i to i8*
     46 
     47   ; Poison memory in prologue: F1F1F1F1F8F3F3F3
     48   ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}}
     49 
     50   ; Memory is unpoisoned at llvm.lifetime.start
     51   call void @llvm.lifetime.start.p0i8(i64 3, i8* %i.ptr)
     52   ; CHECK: store i8 4, i8* %{{[0-9]+}}
     53   ; CHECK-NEXT: llvm.lifetime.start
     54 
     55   store volatile i8 0, i8* %i.ptr
     56   ; CHECK: store volatile
     57 
     58   call void @llvm.lifetime.end.p0i8(i64 4, i8* %i.ptr)
     59   ; CHECK: store i8 -8, i8* %{{[0-9]+}}
     60   ; CHECK-NEXT: call void @llvm.lifetime.end
     61 
     62   ; Memory is poisoned at every call to llvm.lifetime.end
     63   call void @llvm.lifetime.end.p0i8(i64 2, i8* %i.ptr)
     64   ; CHECK: store i8 -8, i8* %{{[0-9]+}}
     65   ; CHECK-NEXT: call void @llvm.lifetime.end
     66 
     67   ; Lifetime intrinsics for array.
     68   %arr = alloca [10 x i32], align 16
     69   %arr.ptr = bitcast [10 x i32]* %arr to i8*
     70 
     71   call void @llvm.lifetime.start.p0i8(i64 40, i8* %arr.ptr)
     72   ; CHECK-DEFAULT: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 40)
     73   ; CHECK-NO-DYNAMIC-NOT: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 40)
     74 
     75   store volatile i8 0, i8* %arr.ptr
     76   ; CHECK: store volatile
     77 
     78   call void @llvm.lifetime.end.p0i8(i64 40, i8* %arr.ptr)
     79   ; CHECK-DEFAULT: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 40)
     80   ; CHECK-NO-DYNAMIC-NOT: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 40)
     81 
     82   ; One more lifetime start/end for the same variable %i.
     83   call void @llvm.lifetime.start.p0i8(i64 2, i8* %i.ptr)
     84   ; CHECK: store i8 4, i8* %{{[0-9]+}}
     85   ; CHECK-NEXT: llvm.lifetime.start
     86 
     87   store volatile i8 0, i8* %i.ptr
     88   ; CHECK: store volatile
     89 
     90   call void @llvm.lifetime.end.p0i8(i64 4, i8* %i.ptr)
     91   ; CHECK: store i8 -8, i8* %{{[0-9]+}}
     92   ; CHECK-NEXT: llvm.lifetime.end
     93 
     94   ; Memory is unpoisoned at function exit (only once).
     95   ; CHECK: store i64 0, i64* %{{[0-9]+}}
     96   ; CHECK-NEXT: ret void
     97   ret void
     98 }
     99 
    100 ; Check that arguments of lifetime may come from phi nodes.
    101 define void @phi_args(i1 %x) sanitize_address {
    102   ; CHECK-LABEL: define void @phi_args(i1 %x)
    103 
    104 entry:
    105   %i = alloca i64, align 4
    106   %i.ptr = bitcast i64* %i to i8*
    107 
    108   ; Poison memory in prologue: F1F1F1F1F8F3F3F3
    109   ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}}
    110 
    111   call void @llvm.lifetime.start.p0i8(i64 8, i8* %i.ptr)
    112   ; CHECK: store i8 0, i8* %{{[0-9]+}}
    113   ; CHECK-NEXT: llvm.lifetime.start
    114 
    115   store volatile i8 0, i8* %i.ptr
    116   ; CHECK: store volatile
    117 
    118   br i1 %x, label %bb0, label %bb1
    119 
    120 bb0:
    121   %i.ptr2 = bitcast i64* %i to i8*
    122   br label %bb1
    123 
    124 bb1:
    125   %i.phi = phi i8* [ %i.ptr, %entry ], [ %i.ptr2, %bb0 ]
    126   call void @llvm.lifetime.end.p0i8(i64 8, i8* %i.phi)
    127   ; CHECK: store i8 -8, i8* %{{[0-9]+}}
    128   ; CHECK-NEXT: llvm.lifetime.end
    129 
    130   ret void
    131   ; CHECK: store i64 0, i64* %{{[0-9]+}}
    132   ; CHECK-NEXT: ret void
    133 }
    134 
    135 ; Check that arguments of lifetime may come from getelementptr nodes.
    136 define void @getelementptr_args() sanitize_address{
    137   ; CHECK-LABEL: define void @getelementptr_args
    138 entry:
    139   %x = alloca [1024 x i8], align 16
    140   %d = alloca i8*, align 8
    141 
    142   ; F1F1F1F1
    143   ; CHECK: store i32 -235802127, i32* %{{[0-9]+}}
    144   ; F3F3F3F3F3F3F3F3
    145   ; CHECK: store i64 -868082074056920077, i64* %{{[0-9]+}}
    146   ; F3F3F3F3F3F3F3F3
    147   ; CHECK: store i64 -868082074056920077, i64* %{{[0-9]+}}
    148 
    149   %0 = getelementptr inbounds [1024 x i8], [1024 x i8]* %x, i64 0, i64 0
    150   call void @llvm.lifetime.start.p0i8(i64 1024, i8* %0)
    151   ; CHECK: call void @__asan_set_shadow_00(i64 %{{[0-9]+}}, i64 128)
    152   ; CHECK-NEXT: call void @llvm.lifetime.start
    153 
    154   store i8* %0, i8** %d, align 8
    155   ; CHECK: store i8
    156 
    157   call void @llvm.lifetime.end.p0i8(i64 1024, i8* %0)
    158   ; CHECK: call void @__asan_set_shadow_f8(i64 %{{[0-9]+}}, i64 128)
    159   ; CHECK-NEXT: call void @llvm.lifetime.end
    160 
    161   ret void
    162   ; CHECK: call void @__asan_set_shadow_00(i64 %{{[0-9]+}}, i64 148)
    163   ; CHECK-NEXT: ret void
    164 }
    165 
    166 define void @zero_sized(i64 %a) #0 {
    167 ; CHECK-LABEL: define void @zero_sized(i64 %a)
    168 
    169 entry:
    170   %a.addr = alloca i64, align 8
    171   %b = alloca [0 x i8], align 1
    172   store i64 %a, i64* %a.addr, align 8
    173 
    174   %0 = bitcast [0 x i8]* %b to i8*
    175   call void @llvm.lifetime.start.p0i8(i64 0, i8* %0) #2
    176   ; CHECK: %{{[0-9]+}} = bitcast
    177   ; CHECK-NEXT: call void @llvm.lifetime.start
    178 
    179   %1 = bitcast [0 x i8]* %b to i8*
    180   call void @llvm.lifetime.end.p0i8(i64 0, i8* %1) #2
    181   ; CHECK-NEXT: %{{[0-9]+}} = bitcast
    182   ; CHECK-NEXT: call void @llvm.lifetime.end
    183 
    184   ret void
    185   ; CHECK-NEXT: ret void
    186 }
    187