Skip to content

Commit 78a165d

Browse files
committed
Fix SILGenBorrowedBaseVisitor::isNonCopyableBaseBorrow
1 parent 75d040f commit 78a165d

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3064,23 +3064,33 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
30643064
forGuaranteedReturn(forGuaranteedReturn),
30653065
forGuaranteedAddressReturn(forGuaranteedAddressReturn) {}
30663066

3067-
static bool isNonCopyableBaseBorrow(SILGenFunction &SGF, Expr *e) {
3067+
static bool isNonCopyableBaseBorrow(SILGenFunction &SGF, Expr *e,
3068+
LValueOptions options) {
30683069
if (auto *m = dyn_cast<MemberRefExpr>(e)) {
30693070
// If our m is a pure noncopyable type or our base is, we need to perform
30703071
// a noncopyable base borrow.
30713072
//
30723073
// DISCUSSION: We can have a noncopyable member_ref_expr with a copyable
30733074
// base if the noncopyable member_ref_expr is from a computed method. In
30743075
// such a case, we want to ensure that we wrap things the right way.
3075-
return m->getType()->isNoncopyable() ||
3076-
m->getBase()->getType()->isNoncopyable();
3076+
if (m->getType()->isNoncopyable() ||
3077+
m->getBase()->getType()->isNoncopyable()) {
3078+
return true;
3079+
}
3080+
3081+
if (options.ForGuaranteedAddressReturn || options.ForGuaranteedReturn) {
3082+
return true;
3083+
}
30773084
}
30783085

30793086
if (auto *le = dyn_cast<LoadExpr>(e)) {
30803087
// Noncopyable type is obviously noncopyable.
30813088
if (le->getType()->isNoncopyable()) {
30823089
return true;
30833090
}
3091+
if (options.ForGuaranteedAddressReturn || options.ForGuaranteedReturn) {
3092+
return true;
3093+
}
30843094
// Otherwise, check if the thing we're loading from is a noncopyable
30853095
// param decl.
30863096
e = le->getSubExpr();
@@ -3092,6 +3102,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
30923102
if (de->getType()->isNoncopyable()) {
30933103
return true;
30943104
}
3105+
if (options.ForGuaranteedAddressReturn || options.ForGuaranteedReturn) {
3106+
return true;
3107+
}
30953108
// If the decl ref refers to a parameter with an explicit ownership
30963109
// modifier, it is not implicitly copyable.
30973110
if (auto pd = dyn_cast<ParamDecl>(de->getDecl())) {
@@ -3115,7 +3128,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
31153128
/// define a visitor stub, defer back to SILGenLValue's visitRec as it is
31163129
/// most-likely a non-lvalue root expression.
31173130
LValue visitExpr(Expr *e, SGFAccessKind accessKind, LValueOptions options) {
3118-
assert(!isNonCopyableBaseBorrow(SGF, e)
3131+
assert(!isNonCopyableBaseBorrow(SGF, e, options)
31193132
&& "unexpected recursion in SILGenLValue::visitRec!");
31203133

31213134
return SGL.visitRec(e, accessKind, options, Orig);
@@ -3172,8 +3185,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
31723185
ManagedValue mv =
31733186
SGF.emitRValueAsSingleValue(e, SGFContext::AllowImmediatePlusZero);
31743187

3175-
if (forGuaranteedReturn && mv.getValue()->getType().isMoveOnly() &&
3176-
!mv.getValue()->getType().isAddress()) {
3188+
if (forGuaranteedReturn && mv.getValue()->getType().isMoveOnly()) {
31773189
// SILGen eagerly generates copy_value +
31783190
// mark_unresolved_non_copyable_value for ~Copyable base values. The
31793191
// generated mark_unresolved_non_copyable_value instructions drive
@@ -3286,11 +3298,14 @@ LValue SILGenLValue::visitRec(Expr *e, SGFAccessKind accessKind,
32863298
// a `borrow x` operator, the operator is used on the base here), we want to
32873299
// apply the lvalue within a formal access to the original value instead of
32883300
// an actual loaded copy.
3289-
if (SILGenBorrowedBaseVisitor::isNonCopyableBaseBorrow(SGF, e) ||
3290-
options.ForGuaranteedReturn) {
3301+
if (SILGenBorrowedBaseVisitor::isNonCopyableBaseBorrow(SGF, e, options)) {
32913302
SILGenBorrowedBaseVisitor visitor(*this, SGF, orig,
3292-
options.ForGuaranteedReturn);
3303+
options.ForGuaranteedReturn,
3304+
options.ForGuaranteedAddressReturn);
32933305
auto accessKind = SGFAccessKind::BorrowedObjectRead;
3306+
if (options.ForGuaranteedAddressReturn) {
3307+
accessKind = SGFAccessKind::BorrowedAddressRead;
3308+
}
32943309
assert(!e->getType()->is<LValueType>()
32953310
&& "maybe need SGFAccessKind::BorrowedAddressRead ?");
32963311
return visitor.visit(e, accessKind, options);

lib/SILGen/SILGenStmt.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,9 @@ void SILGenFunction::emitReturnExpr(SILLocation branchLoc,
773773
F.getConventions().hasGuaranteedResult()
774774
? SGFAccessKind::BorrowedObjectRead
775775
: SGFAccessKind::BorrowedAddressRead,
776-
options.forGuaranteedReturn(true));
776+
F.getConventions().hasGuaranteedResult()
777+
? options.forGuaranteedReturn(true)
778+
: options.forGuaranteedAddressReturn(true));
777779
auto result =
778780
tryEmitProjectedLValue(ret, std::move(lvalue), TSanKind::None);
779781
if (!result) {

0 commit comments

Comments
 (0)