mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
fix handling of large indices in SmallProjectionPath
* Fix the right shift operator which didn't work if the number of bits is exactly 64 * Detect overflow when combining indices Such large indices usually don't appear in real code, except in internal String operations where (potentially large) integer values are treated as pointers. Fixes a compiler crash https://github.com/swiftlang/swift/issues/84372 rdar://160863199
This commit is contained in:
@@ -186,7 +186,7 @@ public struct SmallProjectionPath : Hashable, CustomStringConvertible, NoReflect
|
||||
|
||||
/// Pops \p numBits from the path.
|
||||
private func pop(numBits: Int) -> SmallProjectionPath {
|
||||
return Self(bytes: bytes &>> numBits)
|
||||
return Self(bytes: bytes >> numBits)
|
||||
}
|
||||
|
||||
/// Pops and returns the first path component included the resulting path
|
||||
@@ -210,7 +210,7 @@ public struct SmallProjectionPath : Hashable, CustomStringConvertible, NoReflect
|
||||
// Ignore zero indices
|
||||
return self
|
||||
}
|
||||
if k == .indexedElement {
|
||||
if k == .indexedElement && index &+ i >= 0 {
|
||||
// "Merge" two constant successive indexed elements
|
||||
return pop(numBits: numBits).push(.indexedElement, index: index + i)
|
||||
}
|
||||
@@ -663,7 +663,8 @@ extension SmallProjectionPath {
|
||||
overlapping()
|
||||
predicates()
|
||||
path2path()
|
||||
|
||||
indexedElements()
|
||||
|
||||
func basicPushPop() {
|
||||
let p1 = SmallProjectionPath(.structField, index: 3)
|
||||
.push(.classField, index: 12345678)
|
||||
@@ -925,5 +926,23 @@ extension SmallProjectionPath {
|
||||
assert(result == nil)
|
||||
}
|
||||
}
|
||||
|
||||
func indexedElements() {
|
||||
let p1 = SmallProjectionPath(.indexedElement, index: 1)
|
||||
let (k1, i1, s1) = p1.pop()
|
||||
assert(k1 == .indexedElement && i1 == 1 && s1.isEmpty)
|
||||
|
||||
let p2 = SmallProjectionPath(.indexedElement, index: -1)
|
||||
let (k2, _, s2) = p2.pop()
|
||||
assert(k2 == .anything && s2.isEmpty)
|
||||
|
||||
let p3 = SmallProjectionPath(.indexedElement, index: 0xfffffffffffff)
|
||||
let (k3, i3, s3) = p3.pop()
|
||||
assert(k3 == .indexedElement && i3 == 0xfffffffffffff && s3.isEmpty)
|
||||
|
||||
let p4 = p3.push(.indexedElement, index: Int.max)
|
||||
let (k4, _, s4) = p4.pop()
|
||||
assert(k4 == .anyIndexedElement && s4.isEmpty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user