Skip to content

Commit da3af76

Browse files
committed
SIL: Fix a crash during access path verification.
The access path verification optimizer pass calls `getStaticallyInitializedVariable()`, which was written assuming that the given `SILFunction` would always have a valid return basic block. When the `-unavailable-decl-optimization=stub` option is passed to the frontend, though, any function generated for a declaration marked `@available(*, unavailable)` is rewritten to trap by calling a function that returns `Never`. Therefore the rewritten functions do not have return blocks and passing these functions to `getStaticallyInitializedVariable()` would result in the compiler invoking undefined behavior. Resolves rdar://118281508
1 parent b150656 commit da3af76

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

lib/SIL/IR/SILGlobalVariable.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ static SILGlobalVariable *getStaticallyInitializedVariable(SILFunction *AddrF) {
113113
if (AddrF->isExternalDeclaration())
114114
return nullptr;
115115

116-
auto *RetInst = cast<ReturnInst>(AddrF->findReturnBB()->getTerminator());
116+
auto ReturnBB = AddrF->findReturnBB();
117+
if (ReturnBB == AddrF->end())
118+
return nullptr;
119+
120+
auto *RetInst = cast<ReturnInst>(ReturnBB->getTerminator());
117121
auto *API = dyn_cast<AddressToPointerInst>(RetInst->getOperand());
118122
if (!API)
119123
return nullptr;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// RUN: %target-sil-opt %s -access-path-verification -o /dev/null
2+
3+
sil_stage canonical
4+
5+
import Builtin
6+
import Swift
7+
import SwiftShims
8+
9+
public struct S {
10+
}
11+
12+
@available(*, unavailable)
13+
public struct Unavailable {
14+
@_hasStorage @_hasInitialValue public let i: S { get }
15+
@_hasStorage @_hasInitialValue static let j: S { get }
16+
init()
17+
}
18+
19+
sil [transparent] @$s28accessed_storage_unavailable11UnavailableV1iAA1SVvpfi : $@convention(thin) () -> S {
20+
bb0:
21+
%0 = function_ref @$s28accessed_storage_unavailable11UnavailableV1jAA1SVvau : $@convention(thin) () -> Builtin.RawPointer
22+
%1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer
23+
%2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*S
24+
%3 = load %2 : $*S
25+
return %3 : $S
26+
}
27+
28+
sil hidden [global_init] @$s28accessed_storage_unavailable11UnavailableV1jAA1SVvau : $@convention(thin) () -> Builtin.RawPointer {
29+
bb0:
30+
%0 = function_ref @$ss31_diagnoseUnavailableCodeReacheds5NeverOyF : $@convention(thin) () -> Never
31+
%1 = apply %0() : $@convention(thin) () -> Never
32+
unreachable
33+
}
34+
35+
sil [transparent] @$s28accessed_storage_unavailable11UnavailableV1iAA1SVvg : $@convention(method) (Unavailable) -> S {
36+
bb0(%0 : $Unavailable):
37+
debug_value %0 : $Unavailable, let, name "self", argno 1, implicit
38+
%2 = function_ref @$ss31_diagnoseUnavailableCodeReacheds5NeverOyF : $@convention(thin) () -> Never
39+
%3 = apply %2() : $@convention(thin) () -> Never
40+
unreachable
41+
}
42+
43+
sil private [global_init_once_fn] @$s28accessed_storage_unavailable11UnavailableV1j_WZ : $@convention(c) (Builtin.RawPointer) -> () {
44+
bb0(%0 : $Builtin.RawPointer):
45+
%1 = function_ref @$ss31_diagnoseUnavailableCodeReacheds5NeverOyF : $@convention(thin) () -> Never
46+
%2 = apply %1() : $@convention(thin) () -> Never
47+
unreachable
48+
}
49+
50+
sil [noinline] [_semantics "unavailable_code_reached"] @$ss31_diagnoseUnavailableCodeReacheds5NeverOyF : $@convention(thin) () -> Never
51+
52+
sil_property #Unavailable.i ()
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-swift-frontend -emit-sil -O -unavailable-decl-optimization=stub %s
2+
3+
public struct S {}
4+
5+
@available(*, unavailable)
6+
public struct Unavailable {
7+
public let i = Self.j
8+
9+
static let j = S()
10+
}

0 commit comments

Comments
 (0)