Skip to content

Commit 26db1f2

Browse files
committed
[move-only] Emit a copy_addr instead of a mark_unresolved_move_addr when applying the move operator to move only vars.
The reason why we are doing this is that we want move only addresses to be checked by the move only address checker and not the move operator address checker. rdar://102056097
1 parent 140968c commit 26db1f2

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "swift/AST/Types.h"
4242
#include "swift/Basic/SourceManager.h"
4343
#include "swift/Basic/type_traits.h"
44+
#include "swift/SIL/Consumption.h"
4445
#include "swift/SIL/DynamicCasts.h"
4546
#include "swift/SIL/SILArgument.h"
4647
#include "swift/SIL/SILInstruction.h"
@@ -5934,7 +5935,11 @@ RValue RValueEmitter::visitMoveExpr(MoveExpr *E, SGFContext C) {
59345935
}
59355936

59365937
// If we aren't loadable, then create a temporary initialization and
5937-
// mark_unresolved_move into that.
5938+
// mark_unresolved_move into that if we have a copyable type if we have a move
5939+
// only, just add a copy_addr init.
5940+
//
5941+
// The reason why we do this is that we only use mark_unresolved_move_addr and
5942+
// the move operator checker for copyable values.
59385943
std::unique_ptr<TemporaryInitialization> optTemp;
59395944
optTemp = SGF.emitTemporary(E, SGF.getTypeLowering(subType));
59405945
SILValue toAddr = optTemp->getAddressForInPlaceInitialization(SGF, E);
@@ -5945,7 +5950,12 @@ RValue RValueEmitter::visitMoveExpr(MoveExpr *E, SGFContext C) {
59455950
SGF.emitRValue(subExpr, SGFContext(SGFContext::AllowImmediatePlusZero))
59465951
.getAsSingleValue(SGF, subExpr);
59475952
assert(mv.getType().isAddress());
5948-
SGF.B.createMarkUnresolvedMoveAddr(subExpr, mv.getValue(), toAddr);
5953+
if (mv.getType().isMoveOnly()) {
5954+
SGF.B.createCopyAddr(subExpr, mv.getValue(), toAddr, IsNotTake,
5955+
IsInitialization);
5956+
} else {
5957+
SGF.B.createMarkUnresolvedMoveAddr(subExpr, mv.getValue(), toAddr);
5958+
}
59495959
optTemp->finishInitialization(SGF);
59505960
return RValue(SGF, {optTemp->getManagedAddress()}, subType.getASTType());
59515961
}

lib/SILGen/SILGenLValue.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/AST/GenericEnvironment.h"
3131
#include "swift/AST/PropertyWrappers.h"
3232
#include "swift/AST/TypeCheckRequests.h"
33+
#include "swift/SIL/Consumption.h"
3334
#include "swift/SIL/InstructionUtils.h"
3435
#include "swift/SIL/MemAccessUtils.h"
3536
#include "swift/SIL/PrettyStackTrace.h"
@@ -3914,11 +3915,21 @@ LValue SILGenLValue::visitMoveExpr(MoveExpr *e, SGFAccessKind accessKind,
39143915

39153916
ManagedValue addr = SGF.emitAddressOfLValue(e, std::move(baseLV));
39163917

3917-
// Now create the temporary and
3918+
// Now create the temporary and move our value into there.
39183919
auto temp =
39193920
SGF.emitFormalAccessTemporary(e, SGF.F.getTypeLowering(addr.getType()));
39203921
auto toAddr = temp->getAddressForInPlaceInitialization(SGF, e);
3921-
SGF.B.createMarkUnresolvedMoveAddr(e, addr.getValue(), toAddr);
3922+
3923+
// If we have a move only type, we use a copy_addr that will be handled by the
3924+
// address move only checker. If we have a copyable type, we need to use a
3925+
// mark_unresolved_move_addr to ensure that the move operator checker performs
3926+
// the relevant checking.
3927+
if (addr.getType().isMoveOnly()) {
3928+
SGF.B.createCopyAddr(e, addr.getValue(), toAddr, IsNotTake,
3929+
IsInitialization);
3930+
} else {
3931+
SGF.B.createMarkUnresolvedMoveAddr(e, addr.getValue(), toAddr);
3932+
}
39223933
temp->finishInitialization(SGF);
39233934

39243935
// Now return the temporary in a value component.

test/SILOptimizer/moveonly_addresschecker_diagnostics.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,3 +2061,15 @@ public func closureAndClosureCaptureClassArgUseAfterConsume(_ x2: inout Klass) {
20612061
}
20622062
f()
20632063
}
2064+
2065+
/////////////////////////////
2066+
// Tests For Move Operator //
2067+
/////////////////////////////
2068+
2069+
func moveOperatorTest(_ k: __owned Klass) {
2070+
var k2 = k // expected-error {{'k2' consumed more than once}}
2071+
k2 = Klass()
2072+
let k3 = _move k2 // expected-note {{consuming use}}
2073+
let _ = _move k2 // expected-note {{consuming use}}
2074+
let _ = k3
2075+
}

0 commit comments

Comments
 (0)