@@ -52,6 +52,7 @@ sil @use : $@convention(thin) (Builtin.Int32) -> ()
5252sil @use_a : $@convention(thin) (@in A) -> ()
5353sil @escaped_a_ptr : $@convention(thin) () -> @out A
5454sil @escaped_a : $@convention(thin) () -> Builtin.RawPointer
55+ sil @b_i_plus_one : $@convention(method) (@guaranteed B) -> ()
5556
5657// *NOTE* This does not handle raw pointer since raw pointer is only layout compatible with heap references.
5758// CHECK-FUTURE: sil @store_to_load_forward_unchecked_addr_cast_struct : $@convention(thin) (Optional<A>) -> () {
@@ -547,3 +548,44 @@ bb0(%0 : $*(I32, I32, I32), %1 : $*((I32, I32), I32)):
547548 %63 = tuple (%60 : $(I32, I32), %61 : $(I32, I32), %62 : $(I32, I32, I32))
548549 return %63 : $((I32, I32), (I32, I32), (I32, I32, I32))
549550}
551+
552+ // Tests unchecked_ref_cast between Optional<ClassType1> and ClassType2.
553+ // E? -> B is safe
554+ //
555+ // CHECK-FUTURE: sil @unchecked_ref_cast_from_optional_class
556+ // CHECK: bb3(%6 : $Optional<AnyObject>):
557+ // CHECK: %8 = load %7 : $*Builtin.Int32
558+ // CHECK: %10 = apply %9(%5) : $@convention(method) (@guaranteed B) -> ()
559+ // CHECK: %12 = load %11 : $*Builtin.Int32
560+ // CHECK: return
561+ sil @unchecked_ref_cast_from_optional_class : $@convention(thin) (Optional<E>) -> () {
562+ bb0(%0 : $Optional<E>):
563+ switch_enum %0 : $Optional<E>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
564+
565+ bb1(%1 : $E):
566+ %2 = enum $Optional<E>, #Optional.some!enumelt, %1 : $E
567+ br bb3(%2 : $Optional<E>)
568+
569+ bb2:
570+ %3 = enum $Optional<E>, #Optional.none!enumelt
571+ br bb3(%3 : $Optional<E>)
572+
573+ bb3(%4 : $Optional<E>):
574+ %5 = unchecked_ref_cast %4 : $Optional<E> to $B
575+
576+ %6 = ref_element_addr %5 : $B, #B.i
577+ %7 = begin_access [read] [dynamic] [no_nested_conflict] %6 : $* Builtin.Int32
578+ %8 = load %7 : $*Builtin.Int32
579+ end_access %7 : $*Builtin.Int32
580+
581+ %9 = function_ref @b_i_plus_one : $@convention(method) (@guaranteed B) -> ()
582+ %10 = apply %9(%5) : $@convention(method) (@guaranteed B) -> ()
583+
584+ %11 = begin_access [read] [dynamic] [no_nested_conflict] %6 : $*Builtin.Int32
585+ %12 = load %11 : $*Builtin.Int32
586+ end_access %11 : $*Builtin.Int32
587+
588+ release_value %4 : $Optional<E>
589+ %13 = tuple ()
590+ return %13 : $()
591+ }
0 commit comments