mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[ownership-verifier] Teach the ownership verifier how to handle unreachable code.
There are a few different use cases here: 1. In Raw SIL, no return folding may not have been run yet implying that a call to a no-return function /can/ have arbitrary control flow after it (consider mandatory inlined functions). We need to recognize that the region of code that is strictly post dominated by the no-return function is "transitively unreachable" and thus leaking is ok from that point. *Footnote 1*. 2. In Canonical and Raw SIL, we must recognize that unreachables and no-return functions constitute places where we are allowed to leak. rdar://29791263 ---- *Footnote 1*: The reason why this is done is since we want to emit unreachable code diagnostics when we run no-return folding. By leaving in the relevant code, we have preserved all of the SILLocations on that code allowing us to create really nice diagnostics.
This commit is contained in:
@@ -305,3 +305,22 @@ SILBasicBlock::getFunctionArguments() const {
|
||||
};
|
||||
return makeTransformArrayRef(getArguments(), F);
|
||||
}
|
||||
|
||||
/// Returns true if this block ends in an unreachable or an apply of a
|
||||
/// no-return apply or builtin.
|
||||
bool SILBasicBlock::isNoReturn() const {
|
||||
if (isa<UnreachableInst>(getTerminator()))
|
||||
return true;
|
||||
|
||||
auto Iter = prev_or_begin(getTerminator()->getIterator(), begin());
|
||||
FullApplySite FAS = FullApplySite::isa(const_cast<SILInstruction *>(&*Iter));
|
||||
if (FAS && FAS.isCalleeNoReturn()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto *BI = dyn_cast<BuiltinInst>(&*Iter)) {
|
||||
return BI->getModule().isNoReturnBuiltinOrIntrinsic(BI->getName());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user