Skip to content

Commit dc7879d

Browse files
committed
Fix ASAN error caused by assigning/getting from the same DenseMap in one statement.
The problem would occur if after we accessed the value, we grew the DenseMap to insert the value again. But putting in an extra auto I avoid the problem here. rdar://49609717
1 parent c3ee5ae commit dc7879d

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

lib/SILGen/SILGenPattern.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2622,7 +2622,8 @@ static void switchCaseStmtSuccessCallback(SILGenFunction &SGF,
26222622
}
26232623

26242624
// Ok, we found a match. Update the VarLocs for the case block.
2625-
SGF.VarLocs[expected] = SGF.VarLocs[vd];
2625+
auto v = SGF.VarLocs[vd];
2626+
SGF.VarLocs[expected] = v;
26262627
}
26272628
}
26282629
}

test/SILGen/switch.swift

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,3 +1500,86 @@ func nonTrivialLoadableFallthroughCallee2(_ e : MultipleNonTrivialCaseEnum) {
15001500
}
15011501
}
15021502

1503+
// Make sure that we do not crash while emitting this code.
1504+
//
1505+
// DISCUSSION: The original crash was due to us performing an assignment/lookup
1506+
// on the VarLocs DenseMap in the same statement. This was caught be an
1507+
// asanified compiler. This test is just to make sure we do not regress.
1508+
enum Storage {
1509+
case empty
1510+
case single(Int)
1511+
case pair(Int, Int)
1512+
case array([Int])
1513+
1514+
subscript(range: [Int]) -> Storage {
1515+
get {
1516+
return .empty
1517+
}
1518+
set {
1519+
switch self {
1520+
case .empty:
1521+
break
1522+
case .single(let index):
1523+
break
1524+
case .pair(let first, let second):
1525+
switch (range[0], range[1]) {
1526+
case (0, 0):
1527+
switch newValue {
1528+
case .empty:
1529+
break
1530+
case .single(let other):
1531+
break
1532+
case .pair(let otherFirst, let otherSecond):
1533+
break
1534+
case .array(let other):
1535+
break
1536+
}
1537+
break
1538+
case (0, 1):
1539+
switch newValue {
1540+
case .empty:
1541+
break
1542+
case .single(let other):
1543+
break
1544+
case .pair(let otherFirst, let otherSecond):
1545+
break
1546+
case .array(let other):
1547+
break
1548+
}
1549+
break
1550+
case (0, 2):
1551+
break
1552+
case (1, 2):
1553+
switch newValue {
1554+
case .empty:
1555+
break
1556+
case .single(let other):
1557+
break
1558+
case .pair(let otherFirst, let otherSecond):
1559+
break
1560+
case .array(let other):
1561+
self = .array([first] + other)
1562+
}
1563+
break
1564+
case (2, 2):
1565+
switch newValue {
1566+
case .empty:
1567+
break
1568+
case .single(let other):
1569+
break
1570+
case .pair(let otherFirst, let otherSecond):
1571+
break
1572+
case .array(let other):
1573+
self = .array([first, second] + other)
1574+
}
1575+
break
1576+
default:
1577+
let r = range
1578+
}
1579+
case .array(let indexes):
1580+
break
1581+
}
1582+
}
1583+
}
1584+
}
1585+

0 commit comments

Comments
 (0)