Skip to content

Commit bac26aa

Browse files
committed
[reference-bindings] Fix a verifier error and add a test that validates that we do not crash anymore.
1 parent 91b4757 commit bac26aa

File tree

2 files changed

+78
-51
lines changed

2 files changed

+78
-51
lines changed

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2343,7 +2343,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
23432343
else
23442344
break;
23452345
}
2346-
require(isa<AllocBoxInst>(value) || isa<SILFunctionArgument>(value),
2346+
2347+
auto isLegal = [](SILValue value) {
2348+
if (auto *a = dyn_cast<MarkUnresolvedReferenceBindingInst>(value))
2349+
value = a->getOperand();
2350+
return isa<AllocBoxInst>(value) || isa<SILFunctionArgument>(value);
2351+
};
2352+
require(isLegal(value),
23472353
"Lexical borrows of SILBoxTypes must be of vars or captures.");
23482354
}
23492355

test/Interpreter/reference_bindings.swift

Lines changed: 71 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ var tests = TestSuite("reference bindings")
1010

1111
var global: String = "globalName"
1212
tests.test("global access") {
13-
expectEqual(global, "globalName")
14-
do {
15-
inout x = global
16-
expectEqual(x, "globalName")
17-
}
18-
expectEqual(global, "globalName")
13+
expectEqual(global, "globalName")
14+
do {
15+
inout x = global
16+
expectEqual(x, "globalName")
17+
}
18+
expectEqual(global, "globalName")
1919
}
2020

2121
tests.test("multiple global access exclusivity error")
@@ -25,63 +25,84 @@ tests.test("multiple global access exclusivity error")
2525

2626
@inline(never)
2727
func test(_ x: inout String) {
28-
inout x = global
28+
inout x = global
2929
}
3030
test(&global)
31-
}
31+
}
3232

3333
tests.test("Class Instance Field Access") {
34-
class Klass {
35-
var name: String = "klassName"
36-
}
34+
class Klass {
35+
var name: String = "klassName"
36+
}
3737

38-
let k = Klass()
39-
expectEqual(k.name, "klassName")
40-
do {
41-
inout x = k.name
42-
expectEqual(x, "klassName")
43-
}
44-
expectEqual(k.name, "klassName")
38+
let k = Klass()
39+
expectEqual(k.name, "klassName")
40+
do {
41+
inout x = k.name
42+
expectEqual(x, "klassName")
43+
}
44+
expectEqual(k.name, "klassName")
4545
}
4646

4747
tests.test("Var Access") {
48-
var varName = "varName"
49-
do {
50-
inout x = varName
51-
expectEqual(x, "varName")
52-
}
53-
expectEqual(varName, "varName")
48+
var varName = "varName"
49+
do {
50+
inout x = varName
51+
expectEqual(x, "varName")
52+
}
53+
expectEqual(varName, "varName")
5454

55-
struct S {
56-
var s1 = "field1"
57-
var s2 = "field2"
58-
}
55+
struct S {
56+
var s1 = "field1"
57+
var s2 = "field2"
58+
}
5959

60-
var s = S()
61-
expectEqual(s.s1, "field1")
62-
expectEqual(s.s2, "field2")
63-
do {
64-
inout x = s.s1
65-
expectEqual(x, "field1")
66-
}
67-
expectEqual(s.s1, "field1")
68-
expectEqual(s.s2, "field2")
69-
do {
70-
inout x2 = s.s2
71-
expectEqual(x2, "field2")
72-
}
73-
expectEqual(s.s1, "field1")
74-
expectEqual(s.s2, "field2")
60+
var s = S()
61+
expectEqual(s.s1, "field1")
62+
expectEqual(s.s2, "field2")
63+
do {
64+
inout x = s.s1
65+
expectEqual(x, "field1")
66+
}
67+
expectEqual(s.s1, "field1")
68+
expectEqual(s.s2, "field2")
69+
do {
70+
inout x2 = s.s2
71+
expectEqual(x2, "field2")
72+
}
73+
expectEqual(s.s1, "field1")
74+
expectEqual(s.s2, "field2")
7575
}
7676

7777

7878
tests.test("InOut Access") {
79-
var varName = "varName"
80-
func inoutTest(_ inputX: inout String) {
81-
expectEqual(inputX, "varName")
82-
inout x = inputX
83-
expectEqual(x, "varName")
79+
var varName = "varName"
80+
func inoutTest(_ inputX: inout String) {
81+
expectEqual(inputX, "varName")
82+
inout x = inputX
83+
expectEqual(x, "varName")
84+
}
85+
inoutTest(&varName)
86+
expectEqual(varName, "varName")
87+
}
88+
89+
// We use to hit a verifier error here.
90+
tests.test("Class Use") {
91+
class Klass {
92+
var value: String = "varName"
93+
}
94+
95+
struct S {
96+
var k = Klass()
97+
var i = 5
98+
mutating func x() {
99+
print("\(i)")
84100
}
85-
inoutTest(&varName)
86-
expectEqual(varName, "varName")
101+
}
102+
103+
var s = S()
104+
do {
105+
inout x = s.k
106+
expectEqual(x.value, "varName")
107+
}
87108
}

0 commit comments

Comments
 (0)