Skip to content

Commit 4becc5d

Browse files
Merge pull request #83756 from nate-chandler/assert/20250815/1
[OSSACompleteLifetime] Promote assertion.
2 parents dbd0849 + 0a6c712 commit 4becc5d

File tree

3 files changed

+88
-2
lines changed

3 files changed

+88
-2
lines changed

lib/SIL/Utils/OSSALifetimeCompletion.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,40 @@ void AvailabilityBoundaryVisitor::computeRegion(
333333
// Thus finding a value available at the end of such a block means that
334334
// the block does _not_ must not exits the function normally; in other
335335
// words its terminator must be an UnreachableInst.
336-
assert(isa<UnreachableInst>(block->getTerminator()));
336+
if (!isa<UnreachableInst>(block->getTerminator()) &&
337+
block->getFunction()
338+
->getModule()
339+
.getASTContext()
340+
.SILOpts.VerifySILOwnership) {
341+
llvm::errs() << "Invalid SIL provided to OSSALifetimeCompletion?! {{\n";
342+
llvm::errs() << "OSSALifetimeCompletion is visiting the availability "
343+
"boundary of ";
344+
value->print(llvm::errs());
345+
llvm::errs()
346+
<< "When walking forward from the def to the availability boundary "
347+
"a non-dead-end successor-less block was encountered: bb"
348+
<< block->getDebugID()
349+
<< "\nIts terminator must be an unreachable but is actually "
350+
"instead "
351+
<< *block->getTerminator()
352+
<< "The walk stops at consumes, so reaching such a block means the "
353+
"value was leaked. The function with the leak is as follows:\n";
354+
block->getFunction()->print(llvm::errs());
355+
llvm::errs()
356+
<< "Invalid SIL provided to OSSALifetimeCompletion?! }}\n"
357+
<< "Something that ran before OSSALifetimeCompletion (the current "
358+
"pass, an earlier pass, SILGen) has introduced a leak of this "
359+
"value.\n"
360+
<< "Please rerun the crashing swift-frontend command with the "
361+
"following flags added and file a bug with the output:\n"
362+
<< "-sil-ownership-verify-all -Xllvm '-sil-print-function="
363+
<< block->getFunction()->getName()
364+
<< "' -Xllvm -sil-print-types -Xllvm -sil-print-module-on-error\n";
365+
llvm::errs() << "Use the -disable-sil-ownership-verifier to disable "
366+
"this check.\n";
367+
llvm::report_fatal_error("Invalid lifetime of value whose availability "
368+
"boundary is being visited.");
369+
}
337370
}
338371
for (auto *successor : block->getSuccessorBlocks()) {
339372
regionWorklist.pushIfNotVisited(successor);
@@ -403,7 +436,11 @@ void AvailabilityBoundaryVisitor::visitAvailabilityBoundary(
403436
continue;
404437
}
405438
assert(hasUnavailableSuccessor() ||
406-
isa<UnreachableInst>(block->getTerminator()));
439+
isa<UnreachableInst>(block->getTerminator()) ||
440+
!block->getFunction()
441+
->getModule()
442+
.getASTContext()
443+
.SILOpts.VerifySILOwnership);
407444
visit(block->getTerminator(),
408445
OSSALifetimeCompletion::LifetimeEnd::Boundary);
409446
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: not --crash %target-sil-opt -sil-print-types \
3+
// RUN: -test-runner \
4+
// RUN: %s \
5+
// RUN: -sil-disable-input-verify \
6+
// RUN: -o /dev/null \
7+
// RUN: 2>&1 | tee %t/out
8+
// RUN: %FileCheck %s < %t/out
9+
10+
11+
12+
class C {}
13+
14+
// CHECK: Invalid SIL provided to OSSALifetimeCompletion?!
15+
// CHECK: OSSALifetimeCompletion is visiting the availability boundary of %0 = argument of bb0 : $C
16+
// CHECK: When walking forward from the def to the availability boundary a non-dead-end successor-less block was encountered: bb0
17+
// CHECK: Its terminator must be an unreachable but is actually instead return undef : $() // id: %1
18+
// CHECK: The walk stops at consumes, so reaching such a block means the value was leaked. The function with the leak is as follows:
19+
// CHECK: sil [ossa] @leak_c : $@convention(thin) (@owned C) -> () {
20+
// CHECK: bb0(%0 : @owned $C):
21+
// CHECK: return undef : $()
22+
// CHECK: } // end sil function 'leak_c'
23+
// CHECK: Invalid SIL provided to OSSALifetimeCompletion?!
24+
// CHECK: Something that ran before OSSALifetimeCompletion (the current pass, an earlier pass, SILGen) has introduced a leak of this value.
25+
// CHECK: Please rerun the crashing swift-frontend command with the following flags added and file a bug with the output:
26+
// CHECK: -sil-ownership-verify-all -Xllvm '-sil-print-function=leak_c' -Xllvm -sil-print-types -Xllvm -sil-print-module-on-error
27+
// CHECK: Use the -disable-sil-ownership-verifier to disable this check.
28+
// CHECK: Invalid lifetime of value whose availability boundary is being visited.
29+
sil [ossa] @leak_c : $@convention(thin) (@owned C) -> () {
30+
entry(%c : @owned $C):
31+
specify_test "ossa_lifetime_completion @argument availability"
32+
return undef : $()
33+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-sil-opt -sil-print-types \
2+
// RUN: -test-runner \
3+
// RUN: %s \
4+
// RUN: -sil-disable-input-verify \
5+
// RUN: -disable-sil-ownership-verifier \
6+
// RUN: -o /dev/null \
7+
// RUN: 2>&1 | %FileCheck %s
8+
9+
class C {}
10+
11+
// CHECK: end running test
12+
sil [ossa] @leak_c : $@convention(thin) (@owned C) -> () {
13+
entry(%c : @owned $C):
14+
specify_test "ossa_lifetime_completion @argument availability"
15+
return undef : $()
16+
}

0 commit comments

Comments
 (0)