Skip to content

Commit 01faf1f

Browse files
authored
Merge pull request #78572 from jckarter/synchronize-accessor-check-for-borrow
SILGen: Coordinate access strategy determination with actual codegen in `findStorageReferenceExprForMoveOnly`.
2 parents 5f79319 + 23747bb commit 01faf1f

File tree

2 files changed

+63
-3
lines changed

2 files changed

+63
-3
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3304,23 +3304,61 @@ Expr *SILGenFunction::findStorageReferenceExprForMoveOnly(Expr *argExpr,
33043304
// referenced is a move-only type.
33053305

33063306
AbstractStorageDecl *storage = nullptr;
3307+
AccessSemantics accessSemantics;
33073308
Type type;
33083309
if (auto dre = dyn_cast<DeclRefExpr>(result.getStorageRef())) {
33093310
storage = dyn_cast<AbstractStorageDecl>(dre->getDecl());
33103311
type = dre->getType();
3312+
accessSemantics = dre->getAccessSemantics();
33113313
} else if (auto mre = dyn_cast<MemberRefExpr>(result.getStorageRef())) {
33123314
storage = dyn_cast<AbstractStorageDecl>(mre->getDecl().getDecl());
33133315
type = mre->getType();
3316+
accessSemantics = mre->getAccessSemantics();
33143317
} else if (auto se = dyn_cast<SubscriptExpr>(result.getStorageRef())) {
33153318
storage = dyn_cast<AbstractStorageDecl>(se->getDecl().getDecl());
33163319
type = se->getType();
3320+
accessSemantics = se->getAccessSemantics();
33173321
}
33183322

33193323
if (!storage)
33203324
return nullptr;
3321-
if (!storage->hasStorage() && storage->getReadImpl() != ReadImplKind::Read &&
3322-
storage->getReadImpl() != ReadImplKind::Read2 &&
3323-
storage->getReadImpl() != ReadImplKind::Address) {
3325+
// This should match the strategy computation used in
3326+
// SILGenLValue::visit{DeclRef,Member}RefExpr.
3327+
auto strategy = storage->getAccessStrategy(accessSemantics,
3328+
AccessKind::Read, SGM.M.getSwiftModule(), F.getResilienceExpansion(),
3329+
/* old abi*/ false);
3330+
3331+
switch (strategy.getKind()) {
3332+
case AccessStrategy::Storage:
3333+
// Storage can benefit from direct borrowing/consumption.
3334+
break;
3335+
case AccessStrategy::DirectToAccessor:
3336+
case AccessStrategy::DispatchToAccessor:
3337+
// If the accessor naturally produces a borrow, then we benefit from
3338+
// directly borrowing it.
3339+
switch (strategy.getAccessor()) {
3340+
case AccessorKind::Address:
3341+
case AccessorKind::MutableAddress:
3342+
case AccessorKind::Read:
3343+
case AccessorKind::Read2:
3344+
case AccessorKind::Modify:
3345+
case AccessorKind::Modify2:
3346+
// Accessors that produce a borrow/inout value can be borrowed.
3347+
break;
3348+
3349+
case AccessorKind::Get:
3350+
case AccessorKind::Set:
3351+
case AccessorKind::DistributedGet:
3352+
case AccessorKind::Init:
3353+
case AccessorKind::WillSet:
3354+
case AccessorKind::DidSet:
3355+
// Other accessors can't.
3356+
return nullptr;
3357+
}
3358+
break;
3359+
3360+
case AccessStrategy::MaterializeToTemporary:
3361+
case AccessStrategy::DispatchToDistributedThunk:
33243362
return nullptr;
33253363
}
33263364

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-swift-frontend -emit-sil -verify %s
2+
3+
// rdar://142509673
4+
5+
struct Foo: ~Copyable {
6+
var storage: UnsafeRawPointer
7+
}
8+
9+
class Bar {
10+
class var foo: Foo { fatalError() }
11+
}
12+
13+
func test(foo: borrowing Foo) -> Bool {
14+
fatalError()
15+
}
16+
17+
func test2(bar: Bar.Type) -> Bool {
18+
guard test(foo: bar.foo) else {
19+
return false
20+
}
21+
return true
22+
}

0 commit comments

Comments
 (0)