Skip to content

Commit 1046091

Browse files
committed
[semantic-arc] Implement simple verification of the ownership qualification of copy_value, destroy_value.
rdar://28851920
1 parent 813facf commit 1046091

File tree

2 files changed

+41
-17
lines changed

2 files changed

+41
-17
lines changed

lib/SIL/InstructionUtils.cpp

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -231,28 +231,36 @@ enum class OwnershipQualifiedKind {
231231
Unqualified,
232232
};
233233

234-
} // end anonymous namespace
234+
struct OwnershipQualifiedKindVisitor : SILInstructionVisitor<OwnershipQualifiedKindVisitor, OwnershipQualifiedKind> {
235+
236+
OwnershipQualifiedKind visitValueBase(ValueBase *V) {
237+
return OwnershipQualifierKind::NotApplicable;
238+
}
235239

236-
static OwnershipQualifiedKind
237-
getOwnershipQualifiedKind(const SILInstruction &I) {
238-
switch (I.getKind()) {
239-
case ValueKind::LoadInst:
240-
if (cast<LoadInst>(I).getOwnershipQualifier() ==
241-
LoadOwnershipQualifier::Unqualified)
240+
#define QUALIFIED_INST(CLASS) \
241+
OwnershipQualifiedKind visit ## CLASS(CLASS *I) { \
242+
return OwnershipQualifierKind::Qualified; \
243+
}
244+
QUALIFIED_INST(EndBorrowInst)
245+
QUALIFIED_INST(LoadBorrowInst)
246+
QUALIFIED_INST(CopyValueInst)
247+
QUALIFIED_INST(DestroyValueInst)
248+
#undef QUALIFIED_INST
249+
250+
OwnershipQualifierKind visitLoadInst(LoadInst *LI) {
251+
if (LI->getOwnershipQualifier() == LoadOwnershipQualifier::Unqualified)
242252
return OwnershipQualifiedKind::Unqualified;
243253
return OwnershipQualifiedKind::Qualified;
244-
case ValueKind::StoreInst:
245-
if (cast<StoreInst>(I).getOwnershipQualifier() ==
246-
StoreOwnershipQualifier::Unqualified)
254+
}
255+
256+
OwnershipQualifierKind visitStoreInst(StoreInst *SI) {
257+
if (SI->getOwnershipQualifier() == StoreOwnershipQualifier::Unqualified)
247258
return OwnershipQualifiedKind::Unqualified;
248259
return OwnershipQualifiedKind::Qualified;
249-
case ValueKind::LoadBorrowInst:
250-
case ValueKind::EndBorrowInst:
251-
return OwnershipQualifiedKind::Qualified;
252-
default:
253-
return OwnershipQualifiedKind::NotApplicable;
254260
}
255-
}
261+
};
262+
263+
} // end anonymous namespace
256264

257265
bool FunctionOwnershipEvaluator::evaluate(const SILInstruction &I) {
258266
assert(I.getFunction() == F.get() && "Can not evaluate function ownership "
@@ -265,7 +273,7 @@ bool FunctionOwnershipEvaluator::evaluate(const SILInstruction &I) {
265273
if (!I.getModule().getOptions().EnableSILOwnership)
266274
return true;
267275

268-
switch (getOwnershipQualifiedKind(I)) {
276+
switch (OwnershipQualifiedKindVisitor().visit(I)) {
269277
case OwnershipQualifiedKind::Unqualified: {
270278
// If we already know that the function has unqualified ownership, just
271279
// return early.

lib/SIL/SILVerifier.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,22 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
13491349
"Source value should be an object value");
13501350
}
13511351

1352+
void checkCopyValueInst(CopyValueInst *I) {
1353+
require(I->getOperand()->getType().isObject(),
1354+
"Source value should be an object value");
1355+
requireTrueOrNone(F.hasQualifiedOwnership(),
1356+
"copy_value is only valid in functions with qualified "
1357+
"ownership");
1358+
}
1359+
1360+
void checkDestroyValueInst(DestroyValueInst *I) {
1361+
require(I->getOperand()->getType().isObject(),
1362+
"Source value should be an object value");
1363+
requireTrueOrNone(F.hasQualifiedOwnership(),
1364+
"destroy_value is only valid in functions with qualified "
1365+
"ownership");
1366+
}
1367+
13521368
void checkReleaseValueInst(ReleaseValueInst *I) {
13531369
require(I->getOperand()->getType().isObject(),
13541370
"Source value should be an object value");

0 commit comments

Comments
 (0)