Allow disabling ownership verification via blocklists

This commit is contained in:
Meghana Gupta
2024-12-10 20:31:27 -08:00
parent fe00d20db2
commit bb68264e0e
3 changed files with 48 additions and 15 deletions

View File

@@ -23,5 +23,6 @@ BLOCKLIST_ACTION(ShouldUseBinaryModule)
BLOCKLIST_ACTION(ShouldUseTextualModule)
BLOCKLIST_ACTION(DowngradeInterfaceVerificationFailure)
BLOCKLIST_ACTION(ShouldUseLayoutStringValueWitnesses)
BLOCKLIST_ACTION(ShouldDisableOwnershipVerification)
#undef BLOCKLIST_ACTION

View File

@@ -802,15 +802,24 @@ bool SILValueOwnershipChecker::checkUses() {
return true;
}
bool disableOwnershipVerification(const SILModule &mod) {
if (DisableOwnershipVerification)
return true;
if (mod.getASTContext().blockListConfig.hasBlockListAction(
mod.getSwiftModule()->getRealName().str(),
BlockListKeyKind::ModuleName,
BlockListAction::ShouldDisableOwnershipVerification)) {
return true;
}
return false;
}
//===----------------------------------------------------------------------===//
// Top Level Entrypoints
//===----------------------------------------------------------------------===//
void SILInstruction::verifyOperandOwnership(
SILModuleConventions *silConv) const {
if (DisableOwnershipVerification)
return;
if (isStaticInitializerInst())
return;
@@ -831,11 +840,13 @@ void SILInstruction::verifyOperandOwnership(
!getFunction()->shouldVerifyOwnership())
return;
if (disableOwnershipVerification(getModule()))
return;
// If we are testing the verifier, bail so we only print errors once when
// performing a full verification, instead of additionally in the SILBuilder.
if (IsSILOwnershipVerifierTestingEnabled)
return;
// If this is a terminator instruction, do not verify in SILBuilder. This is
// because when building a new function, one must create the destination block
// first which is an unnatural pattern and pretty brittle.
@@ -903,9 +914,6 @@ verifySILValueHelper(const SILFunction *f, SILValue value,
}
void SILValue::verifyOwnership(DeadEndBlocks *deadEndBlocks) const {
if (DisableOwnershipVerification)
return;
// Do not validate SILUndef values.
if (isa<SILUndef>(*this))
return;
@@ -931,6 +939,14 @@ void SILValue::verifyOwnership(DeadEndBlocks *deadEndBlocks) const {
}
}
// Since we do not have SILUndef, we now know that getFunction() should return
// a real function. Assert in case this assumption is no longer true.
auto *f = (*this)->getFunction();
assert(f && "Instructions and arguments should have a function");
if (disableOwnershipVerification(f->getModule()))
return;
// If we are testing the verifier, bail so we only print errors once when
// performing a full verification a function at a time by the
// OwnershipVerifierStateDumper pass, instead of additionally in the
@@ -938,11 +954,6 @@ void SILValue::verifyOwnership(DeadEndBlocks *deadEndBlocks) const {
if (IsSILOwnershipVerifierTestingEnabled)
return;
// Since we do not have SILUndef, we now know that getFunction() should return
// a real function. Assert in case this assumption is no longer true.
auto *f = (*this)->getFunction();
assert(f && "Instructions and arguments should have a function");
using BehaviorKind = LinearLifetimeChecker::ErrorBehaviorKind;
LinearLifetimeChecker::ErrorBuilder errorBuilder(
*f, BehaviorKind::PrintMessageAndAssert);
@@ -952,7 +963,7 @@ void SILValue::verifyOwnership(DeadEndBlocks *deadEndBlocks) const {
}
void SILModule::verifyOwnership() const {
if (DisableOwnershipVerification)
if (disableOwnershipVerification(*this))
return;
#ifdef NDEBUG
@@ -973,8 +984,6 @@ void SILModule::verifyOwnership() const {
}
void SILFunction::verifyOwnership(DeadEndBlocks *deadEndBlocks) const {
if (DisableOwnershipVerification)
return;
if (!getModule().getOptions().VerifySILOwnership)
return;
@@ -996,6 +1005,9 @@ void SILFunction::verifyOwnership(DeadEndBlocks *deadEndBlocks) const {
if (!hasOwnership() || !shouldVerifyOwnership())
return;
if (disableOwnershipVerification(getModule()))
return;
using BehaviorKind = LinearLifetimeChecker::ErrorBehaviorKind;
unsigned errorCounter = 0;
std::optional<LinearLifetimeChecker::ErrorBuilder> errorBuilder;

View File

@@ -0,0 +1,20 @@
// RUN: %empty-directory(%t)
// RUN: echo "---" > %t/blocklist.yml
// RUN: echo "ShouldDisableOwnershipVerification:" >> %t/blocklist.yml
// RUN: echo " ModuleName:" >> %t/blocklist.yml
// RUN: echo " - Foo" >> %t/blocklist.yml
// RUN: %target-swift-frontend -emit-sil -module-name Foo -blocklist-file %t/blocklist.yml %s | %FileCheck %s
class Klass {}
// CHECK-LABEL: sil @invalid_destroy
// CHECK: strong_release
sil [ossa] @invalid_destroy : $@convention(thin) (@guaranteed Klass) -> () {
bb0(%0 : @guaranteed $Klass):
destroy_value %0 : $Klass
%t = tuple ()
return %t : $()
}