Skip to content

Commit e56cb0b

Browse files
committed
add verifier coverage for explicit_copy_* instructions
At the moment we don't have a proper copy operator in the surface language, so we're enforcing a rule that these instructions are only valid on move-only types. Once we have such an operator, that part can be dropped.
1 parent e619220 commit e56cb0b

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,9 @@ class SILBuilder {
10691069
createExplicitCopyAddr(SILLocation Loc, SILValue srcAddr, SILValue destAddr,
10701070
IsTake_t isTake, IsInitialization_t isInitialize) {
10711071
assert(srcAddr->getType() == destAddr->getType());
1072+
// eventually all types will be allowed with a fully-general copy operator
1073+
assert(srcAddr->getType().isMoveOnly() &&
1074+
"can only explicit-copy a move-only type");
10721075
return insert(new (getModule()) ExplicitCopyAddrInst(
10731076
getSILDebugLocation(Loc), srcAddr, destAddr, isTake, isInitialize));
10741077
}
@@ -1291,6 +1294,9 @@ class SILBuilder {
12911294
assert(!operand->getType().isTrivial(getFunction()) &&
12921295
"Should not be passing trivial values to this api. Use instead "
12931296
"emitCopyValueOperation");
1297+
// eventually all types will be allowed with a fully-general copy operator
1298+
assert(operand->getType().isMoveOnly() &&
1299+
"can only explicit-copy a move-only type");
12941300
return insert(new (getModule())
12951301
ExplicitCopyValueInst(getSILDebugLocation(Loc), operand));
12961302
}

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2822,6 +2822,21 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
28222822
"'MoveOnly' types can only be copied in Raw SIL?!");
28232823
}
28242824

2825+
void checkExplicitCopyAddrInst(ExplicitCopyAddrInst *ecai) {
2826+
require(F.hasOwnership(), "Only valid in OSSA.");
2827+
require(ecai->getSrc()->getType().isAddress(),
2828+
"Src value should be lvalue");
2829+
require(ecai->getDest()->getType().isAddress(),
2830+
"Dest address should be lvalue");
2831+
requireSameType(ecai->getDest()->getType(), ecai->getSrc()->getType(),
2832+
"Store operand type and dest type mismatch");
2833+
require(F.isTypeABIAccessible(ecai->getDest()->getType()),
2834+
"cannot directly copy type with inaccessible ABI");
2835+
// eventually all types will be allowed with a fully-general copy operator
2836+
require(ecai->getSrc()->getType().isMoveOnly(),
2837+
"can only explicit-copy a move-only type");
2838+
}
2839+
28252840
void checkMarkUnresolvedMoveAddrInst(MarkUnresolvedMoveAddrInst *SI) {
28262841
require(F.hasOwnership(), "Only valid in OSSA.");
28272842
require(F.getModule().getStage() == SILStage::Raw, "Only valid in Raw SIL");
@@ -2861,6 +2876,19 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
28612876
"'MoveOnly' types can only be copied in Raw SIL?!");
28622877
}
28632878

2879+
void checkExplicitCopyValueInst(ExplicitCopyValueInst *I) {
2880+
require(I->getOperand()->getType().isObject(),
2881+
"Source value should be an object value");
2882+
require(!I->getOperand()->getType().isTrivial(*I->getFunction()),
2883+
"Source value should be non-trivial");
2884+
require(!fnConv.useLoweredAddresses() || F.hasOwnership(),
2885+
"explicit_copy_value is only valid in functions with qualified "
2886+
"ownership");
2887+
// eventually all types will be allowed with a fully-general copy operator
2888+
require(I->getOperand()->getType().isMoveOnly(),
2889+
"can only explicit-copy a move-only type");
2890+
}
2891+
28642892
void checkDestroyValueInst(DestroyValueInst *I) {
28652893
require(I->getOperand()->getType().isObject(),
28662894
"Source value should be an object value");

0 commit comments

Comments
 (0)