Skip to content

Commit 9acf019

Browse files
authored
Merge pull request #9584 from rjmccall/existential-lvalue-access-ordering
Fix the access order for open-existential l-values
2 parents 24de53f + 897c91e commit 9acf019

File tree

2 files changed

+28
-25
lines changed

2 files changed

+28
-25
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -589,22 +589,12 @@ namespace {
589589
AccessKind accessKind) && override {
590590
assert(base.getType().isExistentialType() &&
591591
"base for open existential component must be an existential");
592-
auto addr = SGF.B.createOpenExistentialAddr(
593-
loc, base.getLValueAddress(), getTypeOfRValue().getAddressType(),
594-
getOpenedExistentialAccessFor(accessKind));
592+
assert(base.getType().isAddress() &&
593+
"base value of open-existential component was not an address?");
595594

596-
if (base.hasCleanup()) {
597-
assert(false && "I believe that we should never end up here. One, we "
598-
"assert above that base is an l-value address and we "
599-
"state l-values don't have associated cleanup. Two, we "
600-
"enter deinit of the buffer but don't have "
601-
"book-keeping for the value. Three, I believe that "
602-
"would mean to have a l-value passed at +1 which I "
603-
"don't believe we do.");
604-
// Leave a cleanup to deinit the existential container.
605-
SGF.enterDeinitExistentialCleanup(base.getValue(), CanType(),
606-
ExistentialRepresentation::Opaque);
607-
}
595+
SILValue addr = SGF.B.createOpenExistentialAddr(
596+
loc, base.getValue(), getTypeOfRValue().getAddressType(),
597+
getOpenedExistentialAccessFor(accessKind));
608598

609599
SGF.setArchetypeOpeningSite(cast<ArchetypeType>(getSubstFormalType()),
610600
addr);
@@ -1926,14 +1916,7 @@ LValue SILGenLValue::visitOpaqueValueExpr(OpaqueValueExpr *e,
19261916
openedExistentials.erase(known);
19271917

19281918
// Do formal evaluation of the underlying existential lvalue.
1929-
LValue existentialLV = visitRec(opened->getExistentialValue(), accessKind);
1930-
1931-
ManagedValue existentialAddr
1932-
= SGF.emitAddressOfLValue(e, std::move(existentialLV), accessKind);
1933-
1934-
// Open up the existential.
1935-
LValue lv;
1936-
lv.add<ValueComponent>(existentialAddr, None, existentialLV.getTypeData());
1919+
LValue lv = visitRec(opened->getExistentialValue(), accessKind);
19371920
lv.add<OpenOpaqueExistentialComponent>(
19381921
cast<ArchetypeType>(opened->getOpenedArchetype()->getCanonicalType()));
19391922
return lv;

test/SILGen/assignment.swift

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
1+
// RUN: %target-swift-frontend -emit-silgen -enforce-exclusivity=checked %s | %FileCheck %s
22

33
class C {}
44

@@ -14,7 +14,7 @@ var a = A()
1414
class D { var child: C = C() }
1515

1616
// Verify that the LHS is formally evaluated before the RHS.
17-
// CHECK: sil hidden @_T010assignment5test1yyF : $@convention(thin) () -> () {
17+
// CHECK-LABEL: sil hidden @_T010assignment5test1yyF : $@convention(thin) () -> () {
1818
func test1() {
1919
// CHECK: [[CTOR:%.*]] = function_ref @_T010assignment1DC{{[_0-9a-zA-Z]*}}fC
2020
// CHECK: [[T0:%.*]] = metatype $@thick D.Type
@@ -26,3 +26,23 @@ func test1() {
2626
// CHECK: apply [[SETTER]]([[C]], [[D]])
2727
D().child = C()
2828
}
29+
30+
// rdar://32039566
31+
protocol P {
32+
var left: Int {get set}
33+
var right: Int {get set}
34+
}
35+
36+
// Verify that the access to the LHS does not begin until after the
37+
// RHS is formally evaluated.
38+
// CHECK-LABEL: sil hidden @_T010assignment15copyRightToLeftyAA1P_pz1p_tF : $@convention(thin) (@inout P) -> () {
39+
func copyRightToLeft(p: inout P) {
40+
// CHECK: bb0(%0 : $*P):
41+
// CHECK: [[READ:%.*]] = begin_access [read] [unknown] %0 : $*P
42+
// CHECK: [[READ_OPEN:%.*]] = open_existential_addr immutable_access [[READ]]
43+
// CHECK: end_access [[READ]] : $*P
44+
// CHECK: [[WRITE:%.*]] = begin_access [modify] [unknown] %0 : $*P
45+
// CHECK: [[WRITE_OPEN:%.*]] = open_existential_addr mutable_access [[WRITE]]
46+
// CHECK: end_access [[WRITE]] : $*P
47+
p.left = p.right
48+
}

0 commit comments

Comments
 (0)