Files
swift-mirror/test/SILOptimizer/moveonly_objectchecker.sil
Andrew Trick 7a29d9d8b6 Fix MoveOnlyObjectCheckerPImpl::check() for mark_dependence.
Handle the presence of mark_dependence instructions after a begin_apply.

Fixes a compiler crash:
"copy of noncopyable typed value. This is a compiler bug. ..."
2025-06-22 17:39:13 -07:00

91 lines
3.6 KiB
Plaintext

// RUN: %target-sil-opt -sil-move-only-object-checker -enable-experimental-feature MoveOnlyClasses -enable-experimental-feature Lifetimes -enable-sil-verify-all -move-only-diagnostics-silently-emit-diagnostics %s | %FileCheck %s
// REQUIRES: swift_feature_MoveOnlyClasses
// REQUIRES: swift_feature_Lifetimes
sil_stage raw
import Swift
class Klass: ~Copyable {}
struct NCNE : ~Copyable, ~Escapable {}
struct NCNEHolder : ~Copyable, ~Escapable {
var ncne: NCNE {
@_lifetime(borrow self)
get
}
}
sil @classUseMoveOnlyWithoutEscaping : $@convention(thin) (@guaranteed Klass) -> ()
sil @read_ncne : $@yield_once @convention(method) (@guaranteed NCNEHolder) -> @lifetime(borrow 0) @yields @guaranteed NCNE
sil @use_ncne : $@convention(thin) (@guaranteed NCNE) -> ()
// CHECK-LABEL: sil [ossa] @chainErrorTest : $@convention(thin) (@guaranteed Klass) -> () {
// CHECK-NOT: copy_value
// CHECK: explicit_copy_value
// CHECK-NOT: copy_value
// CHECK: explicit_copy_value
// CHECK-NOT: copy_valuea
// CHECK: } // end sil function 'chainErrorTest'
sil [ossa] @chainErrorTest : $@convention(thin) (@guaranteed Klass) -> () {
bb0(%0 : @guaranteed $Klass):
%1 = copy_value %0 : $Klass
%2 = mark_unresolved_non_copyable_value [no_consume_or_assign] %1 : $Klass
debug_value %2 : $Klass, let, name "x", argno 1
%4 = copy_value %2 : $Klass
%5 = move_value [lexical] %4 : $Klass
%6 = mark_unresolved_non_copyable_value [consumable_and_assignable] %5 : $Klass
debug_value %6 : $Klass, let, name "x2"
%8 = copy_value %6 : $Klass
%9 = move_value [lexical] %8 : $Klass
%10 = mark_unresolved_non_copyable_value [consumable_and_assignable] %9 : $Klass
debug_value %10 : $Klass, let, name "y2"
%12 = copy_value %10 : $Klass
%13 = move_value [lexical] %12 : $Klass
%14 = mark_unresolved_non_copyable_value [consumable_and_assignable] %13 : $Klass
debug_value %14 : $Klass, let, name "k2"
%16 = copy_value %6 : $Klass
%17 = move_value [lexical] %16 : $Klass
%18 = mark_unresolved_non_copyable_value [consumable_and_assignable] %17 : $Klass
debug_value %18 : $Klass, let, name "k3"
%20 = copy_value %18 : $Klass
%21 = move_value %20 : $Klass
destroy_value %21 : $Klass
%23 = function_ref @classUseMoveOnlyWithoutEscaping : $@convention(thin) (@guaranteed Klass) -> ()
%24 = apply %23(%14) : $@convention(thin) (@guaranteed Klass) -> ()
destroy_value %18 : $Klass
destroy_value %14 : $Klass
destroy_value %10 : $Klass
destroy_value %6 : $Klass
destroy_value %2 : $Klass
%30 = tuple ()
return %30 : $()
}
// CHECK-LABEL: sil [ossa] @testCopyOfMarkDep : $@convention(thin) (@guaranteed NCNEHolder) -> () {
// CHECK-NOT: explicit_copy_value
// CHECK-NOT: copy_value
// CHECK-LABEL: } // end sil function 'testCopyOfMarkDep'
sil [ossa] @testCopyOfMarkDep : $@convention(thin) (@guaranteed NCNEHolder) -> () {
bb0(%0 : @guaranteed $NCNEHolder):
%1 = copy_value %0
%2 = mark_unresolved_non_copyable_value [no_consume_or_assign] %1
debug_value %2, let, name "h", argno 1
%4 = function_ref @read_ncne : $@yield_once @convention(method) (@guaranteed NCNEHolder) -> @lifetime(borrow 0) @yields @guaranteed NCNE
(%5, %6) = begin_apply %4(%2) : $@yield_once @convention(method) (@guaranteed NCNEHolder) -> @lifetime(borrow 0) @yields @guaranteed NCNE
%7 = mark_dependence [unresolved] %5 on %6
%8 = mark_dependence [unresolved] %7 on %2
%9 = copy_value %8
%10 = mark_unresolved_non_copyable_value [no_consume_or_assign] %9
%11 = function_ref @use_ncne : $@convention(thin) (@guaranteed NCNE) -> ()
%12 = apply %11(%10) : $@convention(thin) (@guaranteed NCNE) -> ()
destroy_value %10
%14 = end_apply %6 as $()
destroy_value %2
%16 = tuple ()
return %16
}