Skip to content

Commit 45b81f6

Browse files
committed
[stdlib] add overflow checks for some pointer arithmetic
- Overflow checks added for recent additions to pointer arithmetic (rounding and property pointers). - The basic `advanced(by:)` functions will need to be dealt with separately.
1 parent feecc51 commit 45b81f6

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

stdlib/public/core/UnsafePointer.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,11 @@ public struct UnsafePointer<Pointee>: _Pointer {
371371
to property: KeyPath<Pointee, Property>
372372
) -> UnsafePointer<Property>? {
373373
guard let o = property._storedInlineOffset else { return nil }
374+
_internalInvariant(o >= 0)
375+
_debugPrecondition(
376+
o == 0 || UnsafeRawPointer(self) < UnsafeRawPointer(bitPattern: 0 &- o)!,
377+
"Overflow in pointer arithmetic"
378+
)
374379
return .init(Builtin.gepRaw_Word(_rawValue, o._builtinWordValue))
375380
}
376381

@@ -1088,6 +1093,11 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
10881093
to property: KeyPath<Pointee, Property>
10891094
) -> UnsafePointer<Property>? {
10901095
guard let o = property._storedInlineOffset else { return nil }
1096+
_internalInvariant(o >= 0)
1097+
_debugPrecondition(
1098+
o == 0 || UnsafeRawPointer(self) < UnsafeRawPointer(bitPattern: 0 &- o)!,
1099+
"Overflow in pointer arithmetic"
1100+
)
10911101
return .init(Builtin.gepRaw_Word(_rawValue, o._builtinWordValue))
10921102
}
10931103

@@ -1105,6 +1115,11 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
11051115
to property: WritableKeyPath<Pointee, Property>
11061116
) -> UnsafeMutablePointer<Property>? {
11071117
guard let o = property._storedInlineOffset else { return nil }
1118+
_internalInvariant(o >= 0)
1119+
_debugPrecondition(
1120+
o == 0 || UnsafeRawPointer(self) < UnsafeRawPointer(bitPattern: 0 &- o)!,
1121+
"Overflow in pointer arithmetic"
1122+
)
11081123
return .init(Builtin.gepRaw_Word(_rawValue, o._builtinWordValue))
11091124
}
11101125

stdlib/public/core/UnsafeRawPointer.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ extension UnsafeRawPointer {
499499
public func alignedUp<T>(for type: T.Type) -> Self {
500500
let mask = UInt(Builtin.alignof(T.self)) &- 1
501501
let bits = (UInt(Builtin.ptrtoint_Word(_rawValue)) &+ mask) & ~mask
502+
_debugPrecondition(bits != 0, "Overflow in pointer arithmetic")
502503
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
503504
}
504505

@@ -515,6 +516,7 @@ extension UnsafeRawPointer {
515516
public func alignedDown<T>(for type: T.Type) -> Self {
516517
let mask = UInt(Builtin.alignof(T.self)) &- 1
517518
let bits = UInt(Builtin.ptrtoint_Word(_rawValue)) & ~mask
519+
_debugPrecondition(bits != 0, "Overflow in pointer arithmetic")
518520
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
519521
}
520522

@@ -536,6 +538,7 @@ extension UnsafeRawPointer {
536538
"alignment must be a whole power of 2."
537539
)
538540
let bits = (UInt(Builtin.ptrtoint_Word(_rawValue)) &+ mask) & ~mask
541+
_debugPrecondition(bits != 0, "Overflow in pointer arithmetic")
539542
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
540543
}
541544

@@ -557,6 +560,7 @@ extension UnsafeRawPointer {
557560
"alignment must be a whole power of 2."
558561
)
559562
let bits = UInt(Builtin.ptrtoint_Word(_rawValue)) & ~mask
563+
_debugPrecondition(bits != 0, "Overflow in pointer arithmetic")
560564
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
561565
}
562566
}
@@ -1351,6 +1355,7 @@ extension UnsafeMutableRawPointer {
13511355
public func alignedUp<T>(for type: T.Type) -> Self {
13521356
let mask = UInt(Builtin.alignof(T.self)) &- 1
13531357
let bits = (UInt(Builtin.ptrtoint_Word(_rawValue)) &+ mask) & ~mask
1358+
_debugPrecondition(bits != 0, "Overflow in pointer arithmetic")
13541359
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
13551360
}
13561361

@@ -1367,6 +1372,7 @@ extension UnsafeMutableRawPointer {
13671372
public func alignedDown<T>(for type: T.Type) -> Self {
13681373
let mask = UInt(Builtin.alignof(T.self)) &- 1
13691374
let bits = UInt(Builtin.ptrtoint_Word(_rawValue)) & ~mask
1375+
_debugPrecondition(bits != 0, "Overflow in pointer arithmetic")
13701376
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
13711377
}
13721378

@@ -1388,6 +1394,7 @@ extension UnsafeMutableRawPointer {
13881394
"alignment must be a whole power of 2."
13891395
)
13901396
let bits = (UInt(Builtin.ptrtoint_Word(_rawValue)) &+ mask) & ~mask
1397+
_debugPrecondition(bits != 0, "Overflow in pointer arithmetic")
13911398
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
13921399
}
13931400

@@ -1409,6 +1416,7 @@ extension UnsafeMutableRawPointer {
14091416
"alignment must be a whole power of 2."
14101417
)
14111418
let bits = UInt(Builtin.ptrtoint_Word(_rawValue)) & ~mask
1419+
_debugPrecondition(bits != 0, "Overflow in pointer arithmetic")
14121420
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
14131421
}
14141422
}

0 commit comments

Comments
 (0)