@@ -721,6 +721,67 @@ bb3(%20 : $Error):
721721 throw %20 : $Error
722722}
723723
724+ // -----------------------------------------------------------------------------
725+ // rdar://88664423 (SR-15791: Miscompile under -O with mutating protocol method)
726+ //
727+ // Basic outline (test case has more copies):
728+ // %1 = alloc_stack $PPP
729+ // %2 = init_existential %1
730+ // %3 = open_existential_addr mutable_access %1
731+ // apply mutatingFunc(%3)
732+ // %5 = open_existential_addr %1
733+ // %6 = alloc_stack $@opened P
734+ // copy_addr %5 to [initialization] %6 : $*@opened("381F6B6A-89A1-11EC-999A-D0817AD9985D") PPP
735+ // apply callee3(%5)
736+ //
737+ // When ConcreteExistentialInfo identified the initialization of:
738+ // %4 = alloc_stack [lexical] $PPP, var, name "mergedCommand"
739+ //
740+ // It checks for any mutation other than the initialization itself.
741+ // In this case, `open_existential_addr mutable_access` must be
742+ // considered a possible mutation of the on-stack value.
743+
744+ sil @mutatingFunc : $@convention(method) (@inout S) -> ()
745+
746+ sil @callee3 : $@convention(thin) <τ_0_0 where τ_0_0 : PPP> (@in τ_0_0) -> ()
747+
748+ // CHECK-LABEL: sil @testMutatingCopiedOpenExistential : $@convention(thin) (S) -> () {
749+ // CHECK: bb0(%0 : $S):
750+ // CHECK: [[EXISCP:%.*]] = alloc_stack [lexical] $PPP, var, name "mergedCommand"
751+ // CHECK: apply %{{.*}} : $@convention(method) (@inout S) -> ()
752+ // CHECK: [[OPENED:%.*]] = open_existential_addr mutable_access [[EXISCP]] : $*PPP to $*@opened("381F6B6A-89A1-11EC-999A-D0817AD9985D") PPP
753+ // CHECK: [[OPENEDCP:%.*]] = alloc_stack $@opened("381F6B6A-89A1-11EC-999A-D0817AD9985D") PPP
754+ // CHECK: copy_addr [[OPENED]] to [initialization] [[OPENEDCP]] : $*@opened("381F6B6A-89A1-11EC-999A-D0817AD9985D") PPP
755+ // CHECK: [[CALLEE3:%.*]] = function_ref @callee3 : $@convention(thin) <τ_0_0 where τ_0_0 : PPP> (@in τ_0_0) -> ()
756+ // CHECK: apply [[CALLEE3]]<@opened("381F6B6A-89A1-11EC-999A-D0817AD9985D") PPP>([[OPENEDCP]]) : $@convention(thin) <τ_0_0 where τ_0_0 : PPP> (@in τ_0_0) -> ()
757+ // CHECK-LABEL: } // end sil function 'testMutatingCopiedOpenExistential'
758+ sil @testMutatingCopiedOpenExistential : $@convention(thin) (S) -> () {
759+ bb0(%0 : $S):
760+ %1 = alloc_stack $PPP
761+ %2 = init_existential_addr %1 : $*PPP, $S
762+ store %0 to %2 : $*S
763+ %4 = alloc_stack [lexical] $PPP, var, name "mergedCommand"
764+ copy_addr %1 to [initialization] %4 : $*PPP
765+ %6 = open_existential_addr mutable_access %4 : $*PPP to $*@opened("3818BC52-89A1-11EC-999A-D0817AD9985D") PPP
766+ %7 = unchecked_addr_cast %6 : $*@opened("3818BC52-89A1-11EC-999A-D0817AD9985D") PPP to $*S
767+
768+ %8 = function_ref @mutatingFunc : $@convention(method) (@inout S) -> ()
769+ %9 = apply %8(%7) : $@convention(method) (@inout S) -> ()
770+ %10 = open_existential_addr mutable_access %4 : $*PPP to $*@opened("381F6B6A-89A1-11EC-999A-D0817AD9985D") PPP
771+ %11 = alloc_stack $@opened("381F6B6A-89A1-11EC-999A-D0817AD9985D") PPP
772+ copy_addr %10 to [initialization] %11 : $*@opened("381F6B6A-89A1-11EC-999A-D0817AD9985D") PPP
773+
774+ %13 = function_ref @callee3 : $@convention(thin) <τ_0_0 where τ_0_0 : PPP> (@in τ_0_0) -> ()
775+ %14 = apply %13<@opened("381F6B6A-89A1-11EC-999A-D0817AD9985D") PPP>(%11) : $@convention(thin) <τ_0_0 where τ_0_0 : PPP> (@in τ_0_0) -> ()
776+ dealloc_stack %11 : $*@opened("381F6B6A-89A1-11EC-999A-D0817AD9985D") PPP
777+ destroy_addr %4 : $*PPP
778+ dealloc_stack %4 : $*PPP
779+ destroy_addr %1 : $*PPP
780+ dealloc_stack %1 : $*PPP
781+ %20 = tuple ()
782+ return %20 : $()
783+ }
784+
724785sil_vtable SubscriptionViewControllerBuilder {}
725786sil_vtable SubscriptionViewController {}
726787sil_vtable ViewController {}
0 commit comments