| // RUN: %target-sil-opt -sil-ownership-verifier-enable-testing -enable-sil-verify-all=0 %s -o /dev/null 2>&1 | %FileCheck %s |
| // REQUIRES: asserts |
| |
| sil_stage canonical |
| |
| import Builtin |
| |
| ////////////////// |
| // Declarations // |
| ////////////////// |
| |
| /////////// |
| // Tests // |
| /////////// |
| |
| // Make sure that we correctly flag a double consume by a cond_br of an argument along one edge. |
| // |
| // CHECK-LABEL: Function: 'test1' |
| // CHECK: Found over consume?! |
| // CHECK: Value: %0 = argument of bb0 : $Builtin.NativeObject |
| // CHECK: User: cond_br undef, bb1(%0 : $Builtin.NativeObject), bb2 |
| // CHECK: Block: bb0 |
| sil [ossa] @test1 : $@convention(thin) (@owned Builtin.NativeObject) -> () { |
| bb0(%0 : @owned $Builtin.NativeObject): |
| destroy_value %0 : $Builtin.NativeObject |
| cond_br undef, bb1(%0 : $Builtin.NativeObject), bb2 |
| |
| bb1(%1 : @owned $Builtin.NativeObject): |
| destroy_value %1 : $Builtin.NativeObject |
| br bb2 |
| |
| bb2: |
| %9999 = tuple() |
| return %9999 : $() |
| } |
| |
| // Make sure that we correctly flag a double consume in the next block. |
| // |
| // CHECK-LABEL: Function: 'test2' |
| // CHECK: Found over consume?! |
| // CHECK: Value: %0 = argument of bb0 : $Builtin.NativeObject |
| // CHECK: User: destroy_value %0 : $Builtin.NativeObject |
| // CHECK: Block: bb1 |
| sil [ossa] @test2 : $@convention(thin) (@owned Builtin.NativeObject) -> () { |
| bb0(%0 : @owned $Builtin.NativeObject): |
| cond_br undef, bb1(%0 : $Builtin.NativeObject), bb2 |
| |
| bb1(%1 : @owned $Builtin.NativeObject): |
| destroy_value %0 : $Builtin.NativeObject |
| destroy_value %1 : $Builtin.NativeObject |
| br bb2 |
| |
| bb2: |
| %9999 = tuple() |
| return %9999 : $() |
| } |
| |
| // Now check for use after frees in the consuming block. |
| // |
| // CHECK-LABEL: Function: 'test3' |
| // CHECK: Found use after free?! |
| // CHECK: Value: %0 = argument of bb0 : $Builtin.NativeObject |
| // CHECK: Consuming User: cond_br undef, bb1(%0 : $Builtin.NativeObject), bb2 |
| // CHECK: Non Consuming User: end_borrow %3 : $Builtin.NativeObject |
| // CHECK: Block: bb1 |
| sil [ossa] @test3 : $@convention(thin) (@owned Builtin.NativeObject) -> () { |
| bb0(%0 : @owned $Builtin.NativeObject): |
| cond_br undef, bb1(%0 : $Builtin.NativeObject), bb2 |
| |
| bb1(%1 : @owned $Builtin.NativeObject): |
| %2 = begin_borrow %0 : $Builtin.NativeObject |
| end_borrow %2 : $Builtin.NativeObject |
| destroy_value %1 : $Builtin.NativeObject |
| br bb2 |
| |
| bb2: |
| %9999 = tuple() |
| return %9999 : $() |
| } |