@@ -47,13 +47,22 @@ struct A {
4747 init()
4848}
4949
50+ struct B: ~Copyable, ~Escapable {
51+ let ne: NE
52+
53+ deinit
54+ }
55+
5056struct Holder {
5157 var object: AnyObject
5258}
5359
5460@_addressableForDependencies
5561struct AddressableForDeps {}
5662
63+ sil @getNEPointerToA : $@convention(thin) (@guaranteed NE) -> UnsafePointer<A>
64+ sil @useA : $@convention(thin) (A) -> ()
65+
5766sil @getPtr : $@convention(thin) () -> @out UnsafeRawPointer
5867sil @getSpan : $@convention(thin) (@in_guaranteed AnyObject) -> @lifetime(borrow 0) @out NE
5968
@@ -380,3 +389,53 @@ bb0:
380389 %99 = tuple ()
381390 return %99
382391}
392+
393+ // =============================================================================
394+ // Reduced bugs
395+ // =============================================================================
396+
397+ // rdar149226564 (Compiler crash with non-escapable storing another non-escapable and having a deinit)
398+ //
399+ // Test that initializing LifetimeDependence.Scope from an unidentified enclosing access scope does not
400+ // unwrap nil.
401+ //
402+ // TODO: the mark_dependence should redirect to the drop_deinit, not the struct_element_addr, but AccessBase does not
403+ // currently preserve the address of an unidentified base.
404+ //
405+ // CHECK-LABEL: sil hidden [ossa] @testUnidentified : $@convention(method) (@owned B) -> () {
406+ // CHECK: [[DD:%.*]] = drop_deinit
407+ // CHECK: [[SE:%.*]] = struct_element_addr [[DD]], #B.ne
408+ // CHECK: [[LB:%.*]] = load_borrow
409+ // CHECK: apply %{{.*}} : $@convention(thin) (@guaranteed NE) -> UnsafePointer<A>
410+ // CHECK: mark_dependence [unresolved] %{{.*}} on [[SE]]
411+ // CHECK-LABEL: } // end sil function 'testUnidentified'
412+ sil hidden [ossa] @testUnidentified : $@convention(method) (@owned B) -> () {
413+ bb0(%0 : @owned $B):
414+ %1 = alloc_stack $B, let, name "self", argno 1
415+ %2 = mark_unresolved_non_copyable_value [consumable_and_assignable] %1
416+ store %0 to [init] %2
417+ %4 = drop_deinit %2
418+ debug_value %4, let, name "self", argno 1, expr op_deref
419+ %6 = struct_element_addr %4, #B.ne
420+ %7 = load_borrow %6
421+
422+ %8 = function_ref @getNEPointerToA : $@convention(thin) (@guaranteed NE) -> UnsafePointer<A>
423+ %9 = apply %8(%7) : $@convention(thin) (@guaranteed NE) -> UnsafePointer<A>
424+ %10 = struct_extract %9, #UnsafePointer._rawValue
425+ %11 = pointer_to_address %10 to [strict] $*A
426+ %12 = mark_dependence [unresolved] %11 on %7
427+ %13 = begin_access [read] [unsafe] %12
428+ %14 = load [trivial] %13
429+ end_access %13
430+
431+ %16 = function_ref @useA : $@convention(thin) (A) -> ()
432+ %17 = apply %16(%14) : $@convention(thin) (A) -> ()
433+ end_borrow %7
434+ %19 = struct_element_addr %4, #B.ne
435+ %20 = begin_access [deinit] [static] %19
436+ destroy_addr %20
437+ end_access %20
438+ dealloc_stack %1
439+ %24 = tuple ()
440+ return %24
441+ }
0 commit comments