@@ -650,15 +650,46 @@ void SILGenFunction::emitCaptures(SILLocation loc,
650
650
651
651
// Get an address value for a SILValue if it is address only in an type
652
652
// expansion context without opaque archetype substitution.
653
- auto getAddressValue = [&](SILValue entryValue, bool forceCopy) -> SILValue {
654
- if (SGM.M .useLoweredAddresses ()
655
- && SGM.Types
656
- .getTypeLowering (
657
- valueType,
658
- TypeExpansionContext::noOpaqueTypeArchetypesSubstitution (
659
- expansion.getResilienceExpansion ()))
660
- .isAddressOnly ()
661
- && !entryValue->getType ().isAddress ()) {
653
+ auto getAddressValue = [&](SILValue entryValue, bool forceCopy,
654
+ bool forLValue) -> SILValue {
655
+ if (!SGM.M .useLoweredAddresses () && !forLValue && !isPack) {
656
+ // In opaque values mode, addresses aren't used except by lvalues.
657
+ auto &lowering = getTypeLowering (entryValue->getType ());
658
+ if (entryValue->getType ().isAddress ()) {
659
+ // If the value is currently an address, load it, copying if needed.
660
+ if (lowering.isTrivial ()) {
661
+ SILValue result = lowering.emitLoad (
662
+ B, loc, entryValue, LoadOwnershipQualifier::Trivial);
663
+ return result;
664
+ }
665
+ if (forceCopy) {
666
+ SILValue result =
667
+ lowering.emitLoadOfCopy (B, loc, entryValue, IsNotTake);
668
+ enterDestroyCleanup (result);
669
+ return result;
670
+ } else {
671
+ auto load = B.createLoadBorrow (
672
+ loc, ManagedValue::forBorrowedRValue (entryValue))
673
+ .getValue ();
674
+ return load;
675
+ }
676
+ } else {
677
+ // Otherwise, just return it, copying if needed.
678
+ if (forceCopy && !lowering.isTrivial ()) {
679
+ auto result = B.emitCopyValueOperation (loc, entryValue);
680
+ // enterDestroyCleanup(result);
681
+ return result;
682
+ }
683
+ return entryValue;
684
+ }
685
+ } else if (SGM.M .useLoweredAddresses () &&
686
+ SGM.Types
687
+ .getTypeLowering (
688
+ valueType, TypeExpansionContext::
689
+ noOpaqueTypeArchetypesSubstitution (
690
+ expansion.getResilienceExpansion ()))
691
+ .isAddressOnly () &&
692
+ !entryValue->getType ().isAddress ()) {
662
693
663
694
assert (!isPack);
664
695
@@ -684,7 +715,6 @@ void SILGenFunction::emitCaptures(SILLocation loc,
684
715
if (!forceCopy)
685
716
enterDestroyCleanup (addr);
686
717
return addr;
687
-
688
718
} else if (forceCopy) {
689
719
// We cannot pass a valid SILDebugVariable while creating the temp here
690
720
// See rdar://60425582
@@ -755,26 +785,38 @@ void SILGenFunction::emitCaptures(SILLocation loc,
755
785
if (canGuarantee) {
756
786
// No-escaping stored declarations are captured as the
757
787
// address of the value.
758
- auto addr = getAddressValue (val, /* forceCopy= */ false );
759
- capturedArgs. push_back ( ManagedValue::forBorrowedRValue (addr) );
760
- }
761
- else if (!silConv. useLoweredAddresses ()) {
762
- capturedArgs. push_back (B. copyOwnedObjectRValue (
763
- loc, val, ManagedValue::ScopeKind::Lexical ));
788
+ auto addr =
789
+ getAddressValue (val, /* forceCopy= */ false , /* forLValue= */ false );
790
+ capturedArgs. push_back (
791
+ addr-> getOwnershipKind () == OwnershipKind::Owned
792
+ ? ManagedValue::forOwnedRValue (addr, CleanupHandle::invalid ())
793
+ : ManagedValue::forBorrowedRValue (addr ));
764
794
} else {
765
- auto addr = getAddressValue (val, /* forceCopy=*/ true );
795
+ auto addr =
796
+ getAddressValue (val, /* forceCopy=*/ true , /* forLValue=*/ false );
797
+ if (!useLoweredAddresses ()) {
798
+ auto &lowering = getTypeLowering (addr->getType ());
799
+ auto rvalue =
800
+ lowering.isTrivial ()
801
+ ? ManagedValue::forObjectRValueWithoutOwnership (addr)
802
+ : ManagedValue::forOwnedRValue (addr,
803
+ CleanupHandle::invalid ());
804
+ capturedArgs.push_back (rvalue);
805
+ break ;
806
+ }
766
807
// If our address is move only wrapped, unwrap it.
767
808
if (addr->getType ().isMoveOnlyWrapped ()) {
768
809
addr = B.createMoveOnlyWrapperToCopyableAddr (loc, addr);
769
810
}
770
- capturedArgs.push_back (ManagedValue::forLValue (addr));
811
+ capturedArgs.push_back (ManagedValue::forOwnedAddressRValue (
812
+ addr, CleanupHandle::invalid ()));
771
813
}
772
814
break ;
773
815
}
774
816
case CaptureKind::StorageAddress: {
775
817
assert (!isPack);
776
818
777
- auto addr = getAddressValue (val, /* forceCopy=*/ false );
819
+ auto addr = getAddressValue (val, /* forceCopy=*/ false , /* forLValue= */ true );
778
820
779
821
// No-escaping stored declarations are captured as the
780
822
// address of the value.
0 commit comments