Skip to content

Commit 64a984b

Browse files
committed
[move-only] Validate in the SILVerifier that we only have copy_addr [init]/load [copy] on move only values in Raw SIL.
This is already an invariant for copy_value and now that I am implementing move semantics for addresses, it makes sense to ban those in a similar way. Specifically, we are enforcing the invariant that move only types are allowed to be copied in Raw SIL, but not in later parts of SIL. For those who are unaware, we then run checkers later to validate that we preserve ownership semantics.
1 parent 2baa1e4 commit 64a984b

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,6 +2189,10 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
21892189
"Load with unqualified ownership in a qualified function");
21902190
break;
21912191
case LoadOwnershipQualifier::Copy:
2192+
require(LI->getModule().getStage() == SILStage::Raw ||
2193+
!LI->getOperand()->getType().isMoveOnly(),
2194+
"'MoveOnly' types can only be copied in Raw SIL?!");
2195+
[[fallthrough]];
21922196
case LoadOwnershipQualifier::Take:
21932197
require(F.hasOwnership(),
21942198
"Load with qualified ownership in an unqualified function");
@@ -2655,15 +2659,17 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
26552659
require(Elt->getType().isAddress(), "MFE must refer to variable addrs");
26562660
}
26572661

2658-
void checkCopyAddrInst(CopyAddrInst *SI) {
2659-
require(SI->getSrc()->getType().isAddress(),
2660-
"Src value should be lvalue");
2661-
require(SI->getDest()->getType().isAddress(),
2662+
void checkCopyAddrInst(CopyAddrInst *cai) {
2663+
require(cai->getSrc()->getType().isAddress(), "Src value should be lvalue");
2664+
require(cai->getDest()->getType().isAddress(),
26622665
"Dest address should be lvalue");
2663-
requireSameType(SI->getDest()->getType(), SI->getSrc()->getType(),
2666+
requireSameType(cai->getDest()->getType(), cai->getSrc()->getType(),
26642667
"Store operand type and dest type mismatch");
2665-
require(F.isTypeABIAccessible(SI->getDest()->getType()),
2668+
require(F.isTypeABIAccessible(cai->getDest()->getType()),
26662669
"cannot directly copy type with inaccessible ABI");
2670+
require(cai->getModule().getStage() == SILStage::Raw ||
2671+
(cai->isTakeOfSrc() || !cai->getSrc()->getType().isMoveOnly()),
2672+
"'MoveOnly' types can only be copied in Raw SIL?!");
26672673
}
26682674

26692675
void checkMarkUnresolvedMoveAddrInst(MarkUnresolvedMoveAddrInst *SI) {

0 commit comments

Comments
 (0)