Skip to content

Commit 1bc56dc

Browse files
committed
[stdlib] Mark some parameters @_nonEphemeral
These include the pointer-to-pointer and pointer-to-buffer-pointer initialiser parameters amongst a couple of others, such as `Unmanaged.fromOpaque`, and the source for the `move[...]` family of methods.
1 parent d0dbbf9 commit 1bc56dc

14 files changed

+557
-44
lines changed

stdlib/public/core/BridgeObjectiveC.swift

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,9 @@ public struct AutoreleasingUnsafeMutablePointer<Pointee /* TODO : class */>
509509
/// - Warning: Accessing `pointee` as a type that is unrelated to
510510
/// the underlying memory's bound type is undefined.
511511
@usableFromInline @_transparent
512-
internal init<U>(_ from: UnsafePointer<U>) {
512+
internal init<U>(
513+
@_nonEphemeral _ from: UnsafePointer<U>
514+
) {
513515
self._rawValue = from._rawValue
514516
}
515517

@@ -523,7 +525,9 @@ public struct AutoreleasingUnsafeMutablePointer<Pointee /* TODO : class */>
523525
/// - Warning: Accessing `pointee` as a type that is unrelated to
524526
/// the underlying memory's bound type is undefined.
525527
@usableFromInline @_transparent
526-
internal init?<U>(_ from: UnsafePointer<U>?) {
528+
internal init?<U>(
529+
@_nonEphemeral _ from: UnsafePointer<U>?
530+
) {
527531
guard let unwrapped = from else { return nil }
528532
self.init(unwrapped)
529533
}
@@ -535,7 +539,9 @@ extension UnsafeMutableRawPointer {
535539
///
536540
/// - Parameter other: The pointer to convert.
537541
@_transparent
538-
public init<T>(_ other: AutoreleasingUnsafeMutablePointer<T>) {
542+
public init<T>(
543+
@_nonEphemeral _ other: AutoreleasingUnsafeMutablePointer<T>
544+
) {
539545
_rawValue = other._rawValue
540546
}
541547

@@ -545,7 +551,9 @@ extension UnsafeMutableRawPointer {
545551
/// - Parameter other: The pointer to convert. If `other` is `nil`, the
546552
/// result is `nil`.
547553
@_transparent
548-
public init?<T>(_ other: AutoreleasingUnsafeMutablePointer<T>?) {
554+
public init?<T>(
555+
@_nonEphemeral _ other: AutoreleasingUnsafeMutablePointer<T>?
556+
) {
549557
guard let unwrapped = other else { return nil }
550558
self.init(unwrapped)
551559
}
@@ -557,7 +565,9 @@ extension UnsafeRawPointer {
557565
///
558566
/// - Parameter other: The pointer to convert.
559567
@_transparent
560-
public init<T>(_ other: AutoreleasingUnsafeMutablePointer<T>) {
568+
public init<T>(
569+
@_nonEphemeral _ other: AutoreleasingUnsafeMutablePointer<T>
570+
) {
561571
_rawValue = other._rawValue
562572
}
563573

@@ -567,7 +577,9 @@ extension UnsafeRawPointer {
567577
/// - Parameter other: The pointer to convert. If `other` is `nil`, the
568578
/// result is `nil`.
569579
@_transparent
570-
public init?<T>(_ other: AutoreleasingUnsafeMutablePointer<T>?) {
580+
public init?<T>(
581+
@_nonEphemeral _ other: AutoreleasingUnsafeMutablePointer<T>?
582+
) {
571583
guard let unwrapped = other else { return nil }
572584
self.init(unwrapped)
573585
}

stdlib/public/core/CTypes.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,30 +141,30 @@ public struct OpaquePointer {
141141

142142
/// Converts a typed `UnsafePointer` to an opaque C pointer.
143143
@_transparent
144-
public init<T>(_ from: UnsafePointer<T>) {
144+
public init<T>(@_nonEphemeral _ from: UnsafePointer<T>) {
145145
self._rawValue = from._rawValue
146146
}
147147

148148
/// Converts a typed `UnsafePointer` to an opaque C pointer.
149149
///
150150
/// The result is `nil` if `from` is `nil`.
151151
@_transparent
152-
public init?<T>(_ from: UnsafePointer<T>?) {
152+
public init?<T>(@_nonEphemeral _ from: UnsafePointer<T>?) {
153153
guard let unwrapped = from else { return nil }
154154
self.init(unwrapped)
155155
}
156156

157157
/// Converts a typed `UnsafeMutablePointer` to an opaque C pointer.
158158
@_transparent
159-
public init<T>(_ from: UnsafeMutablePointer<T>) {
159+
public init<T>(@_nonEphemeral _ from: UnsafeMutablePointer<T>) {
160160
self._rawValue = from._rawValue
161161
}
162162

163163
/// Converts a typed `UnsafeMutablePointer` to an opaque C pointer.
164164
///
165165
/// The result is `nil` if `from` is `nil`.
166166
@_transparent
167-
public init?<T>(_ from: UnsafeMutablePointer<T>?) {
167+
public init?<T>(@_nonEphemeral _ from: UnsafeMutablePointer<T>?) {
168168
guard let unwrapped = from else { return nil }
169169
self.init(unwrapped)
170170
}

stdlib/public/core/MigrationSupport.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,16 +390,16 @@ extension UnsafeMutablePointer {
390390

391391
extension UnsafeMutableRawPointer {
392392
@available(*, unavailable, renamed: "init(mutating:)")
393-
public init(_ from: UnsafeRawPointer) { Builtin.unreachable() }
393+
public init(@_nonEphemeral _ from: UnsafeRawPointer) { Builtin.unreachable() }
394394

395395
@available(*, unavailable, renamed: "init(mutating:)")
396-
public init?(_ from: UnsafeRawPointer?) { Builtin.unreachable() }
396+
public init?(@_nonEphemeral _ from: UnsafeRawPointer?) { Builtin.unreachable() }
397397

398398
@available(*, unavailable, renamed: "init(mutating:)")
399-
public init<T>(_ from: UnsafePointer<T>) { Builtin.unreachable() }
399+
public init<T>(@_nonEphemeral _ from: UnsafePointer<T>) { Builtin.unreachable() }
400400

401401
@available(*, unavailable, renamed: "init(mutating:)")
402-
public init?<T>(_ from: UnsafePointer<T>?) { Builtin.unreachable() }
402+
public init?<T>(@_nonEphemeral _ from: UnsafePointer<T>?) { Builtin.unreachable() }
403403
}
404404

405405
extension UnsafeRawPointer: _CustomPlaygroundQuickLookable {

stdlib/public/core/Pointer.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ extension _Pointer {
8080
///
8181
/// - Parameter other: The typed pointer to convert.
8282
@_transparent
83-
public init(_ other: Self) {
83+
public init(@_nonEphemeral _ other: Self) {
8484
self.init(other._rawValue)
8585
}
8686

@@ -89,7 +89,7 @@ extension _Pointer {
8989
/// - Parameter other: The typed pointer to convert. If `other` is `nil`, the
9090
/// result is `nil`.
9191
@_transparent
92-
public init?(_ other: Self?) {
92+
public init?(@_nonEphemeral _ other: Self?) {
9393
guard let unwrapped = other else { return nil }
9494
self.init(unwrapped._rawValue)
9595
}
@@ -267,17 +267,17 @@ extension UInt {
267267
// Pointer arithmetic operators (formerly via Strideable)
268268
extension Strideable where Self: _Pointer {
269269
@_transparent
270-
public static func + (lhs: Self, rhs: Self.Stride) -> Self {
270+
public static func + (@_nonEphemeral lhs: Self, rhs: Self.Stride) -> Self {
271271
return lhs.advanced(by: rhs)
272272
}
273273

274274
@_transparent
275-
public static func + (lhs: Self.Stride, rhs: Self) -> Self {
275+
public static func + (lhs: Self.Stride, @_nonEphemeral rhs: Self) -> Self {
276276
return rhs.advanced(by: lhs)
277277
}
278278

279279
@_transparent
280-
public static func - (lhs: Self, rhs: Self.Stride) -> Self {
280+
public static func - (@_nonEphemeral lhs: Self, rhs: Self.Stride) -> Self {
281281
return lhs.advanced(by: -rhs)
282282
}
283283

stdlib/public/core/Unmanaged.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ public struct Unmanaged<Instance: AnyObject> {
3131
/// - Parameter value: An opaque C pointer.
3232
/// - Returns: An unmanaged class reference to `value`.
3333
@_transparent
34-
public static func fromOpaque(_ value: UnsafeRawPointer) -> Unmanaged {
34+
public static func fromOpaque(
35+
@_nonEphemeral _ value: UnsafeRawPointer
36+
) -> Unmanaged {
3537
return Unmanaged(_private: unsafeBitCast(value, to: Instance.self))
3638
}
3739

stdlib/public/core/UnsafeBufferPointer.swift.gyb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,9 @@ extension Unsafe${Mutable}BufferPointer {
398398
/// - count: The number of instances in the buffer. `count` must not be
399399
/// negative.
400400
@inlinable // unsafe-performance
401-
public init(start: Unsafe${Mutable}Pointer<Element>?, count: Int) {
401+
public init(
402+
@_nonEphemeral start: Unsafe${Mutable}Pointer<Element>?, count: Int
403+
) {
402404
_precondition(
403405
count >= 0, "Unsafe${Mutable}BufferPointer with negative count")
404406
_precondition(

stdlib/public/core/UnsafePointer.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
530530
///
531531
/// - Parameter other: The immutable pointer to convert.
532532
@_transparent
533-
public init(mutating other: UnsafePointer<Pointee>) {
533+
public init(@_nonEphemeral mutating other: UnsafePointer<Pointee>) {
534534
self._rawValue = other._rawValue
535535
}
536536

@@ -540,7 +540,7 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
540540
/// - Parameter other: The immutable pointer to convert. If `other` is `nil`,
541541
/// the result is `nil`.
542542
@_transparent
543-
public init?(mutating other: UnsafePointer<Pointee>?) {
543+
public init?(@_nonEphemeral mutating other: UnsafePointer<Pointee>?) {
544544
guard let unwrapped = other else { return nil }
545545
self.init(mutating: unwrapped)
546546
}
@@ -550,7 +550,7 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
550550
///
551551
/// - Parameter other: The pointer to convert.
552552
@_transparent
553-
public init(_ other: UnsafeMutablePointer<Pointee>) {
553+
public init(@_nonEphemeral _ other: UnsafeMutablePointer<Pointee>) {
554554
self._rawValue = other._rawValue
555555
}
556556

@@ -560,7 +560,7 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
560560
/// - Parameter other: The pointer to convert. If `other` is `nil`, the
561561
/// result is `nil`.
562562
@_transparent
563-
public init?(_ other: UnsafeMutablePointer<Pointee>?) {
563+
public init?(@_nonEphemeral _ other: UnsafeMutablePointer<Pointee>?) {
564564
guard let unwrapped = other else { return nil }
565565
self.init(unwrapped)
566566
}
@@ -784,7 +784,9 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
784784
/// - count: The number of instances to move from `source` to this
785785
/// pointer's memory. `count` must not be negative.
786786
@inlinable
787-
public func moveInitialize(from source: UnsafeMutablePointer, count: Int) {
787+
public func moveInitialize(
788+
@_nonEphemeral from source: UnsafeMutablePointer, count: Int
789+
) {
788790
_debugPrecondition(
789791
count >= 0, "UnsafeMutablePointer.moveInitialize with negative count")
790792
if self < source || self >= source + count {
@@ -855,7 +857,9 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
855857
/// - count: The number of instances to move from `source` to this
856858
/// pointer's memory. `count` must not be negative.
857859
@inlinable
858-
public func moveAssign(from source: UnsafeMutablePointer, count: Int) {
860+
public func moveAssign(
861+
@_nonEphemeral from source: UnsafeMutablePointer, count: Int
862+
) {
859863
_debugPrecondition(
860864
count >= 0, "UnsafeMutablePointer.moveAssign(from:) with negative count")
861865
_debugPrecondition(

stdlib/public/core/UnsafeRawBufferPointer.swift.gyb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,9 @@ extension Unsafe${Mutable}RawBufferPointer {
429429
/// - count: The number of bytes to include in the buffer. `count` must not
430430
/// be negative.
431431
@inlinable
432-
public init(start: Unsafe${Mutable}RawPointer?, count: Int) {
432+
public init(
433+
@_nonEphemeral start: Unsafe${Mutable}RawPointer?, count: Int
434+
) {
433435
_precondition(count >= 0, "${Self} with negative count")
434436
_precondition(count == 0 || start != nil,
435437
"${Self} has a nil start and nonzero count")

stdlib/public/core/UnsafeRawPointer.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public struct UnsafeRawPointer: _Pointer {
191191
///
192192
/// - Parameter other: The typed pointer to convert.
193193
@_transparent
194-
public init<T>(_ other: UnsafePointer<T>) {
194+
public init<T>(@_nonEphemeral _ other: UnsafePointer<T>) {
195195
_rawValue = other._rawValue
196196
}
197197

@@ -204,7 +204,7 @@ public struct UnsafeRawPointer: _Pointer {
204204
/// - Parameter other: The typed pointer to convert. If `other` is `nil`, the
205205
/// result is `nil`.
206206
@_transparent
207-
public init?<T>(_ other: UnsafePointer<T>?) {
207+
public init?<T>(@_nonEphemeral _ other: UnsafePointer<T>?) {
208208
guard let unwrapped = other else { return nil }
209209
_rawValue = unwrapped._rawValue
210210
}
@@ -217,7 +217,7 @@ public struct UnsafeRawPointer: _Pointer {
217217
///
218218
/// - Parameter other: The mutable raw pointer to convert.
219219
@_transparent
220-
public init(_ other: UnsafeMutableRawPointer) {
220+
public init(@_nonEphemeral _ other: UnsafeMutableRawPointer) {
221221
_rawValue = other._rawValue
222222
}
223223

@@ -230,7 +230,7 @@ public struct UnsafeRawPointer: _Pointer {
230230
/// - Parameter other: The mutable raw pointer to convert. If `other` is
231231
/// `nil`, the result is `nil`.
232232
@_transparent
233-
public init?(_ other: UnsafeMutableRawPointer?) {
233+
public init?(@_nonEphemeral _ other: UnsafeMutableRawPointer?) {
234234
guard let unwrapped = other else { return nil }
235235
_rawValue = unwrapped._rawValue
236236
}
@@ -243,7 +243,7 @@ public struct UnsafeRawPointer: _Pointer {
243243
///
244244
/// - Parameter other: The typed pointer to convert.
245245
@_transparent
246-
public init<T>(_ other: UnsafeMutablePointer<T>) {
246+
public init<T>(@_nonEphemeral _ other: UnsafeMutablePointer<T>) {
247247
_rawValue = other._rawValue
248248
}
249249

@@ -256,7 +256,7 @@ public struct UnsafeRawPointer: _Pointer {
256256
/// - Parameter other: The typed pointer to convert. If `other` is `nil`, the
257257
/// result is `nil`.
258258
@_transparent
259-
public init?<T>(_ other: UnsafeMutablePointer<T>?) {
259+
public init?<T>(@_nonEphemeral _ other: UnsafeMutablePointer<T>?) {
260260
guard let unwrapped = other else { return nil }
261261
_rawValue = unwrapped._rawValue
262262
}
@@ -543,7 +543,7 @@ public struct UnsafeMutableRawPointer: _Pointer {
543543
///
544544
/// - Parameter other: The typed pointer to convert.
545545
@_transparent
546-
public init<T>(_ other: UnsafeMutablePointer<T>) {
546+
public init<T>(@_nonEphemeral _ other: UnsafeMutablePointer<T>) {
547547
_rawValue = other._rawValue
548548
}
549549

@@ -556,7 +556,7 @@ public struct UnsafeMutableRawPointer: _Pointer {
556556
/// - Parameter other: The typed pointer to convert. If `other` is `nil`, the
557557
/// result is `nil`.
558558
@_transparent
559-
public init?<T>(_ other: UnsafeMutablePointer<T>?) {
559+
public init?<T>(@_nonEphemeral _ other: UnsafeMutablePointer<T>?) {
560560
guard let unwrapped = other else { return nil }
561561
_rawValue = unwrapped._rawValue
562562
}
@@ -569,7 +569,7 @@ public struct UnsafeMutableRawPointer: _Pointer {
569569
///
570570
/// - Parameter other: The immutable raw pointer to convert.
571571
@_transparent
572-
public init(mutating other: UnsafeRawPointer) {
572+
public init(@_nonEphemeral mutating other: UnsafeRawPointer) {
573573
_rawValue = other._rawValue
574574
}
575575

@@ -582,7 +582,7 @@ public struct UnsafeMutableRawPointer: _Pointer {
582582
/// - Parameter other: The immutable raw pointer to convert. If `other` is
583583
/// `nil`, the result is `nil`.
584584
@_transparent
585-
public init?(mutating other: UnsafeRawPointer?) {
585+
public init?(@_nonEphemeral mutating other: UnsafeRawPointer?) {
586586
guard let unwrapped = other else { return nil }
587587
_rawValue = unwrapped._rawValue
588588
}
@@ -997,23 +997,23 @@ extension UnsafeMutableRawPointer: Strideable {
997997

998998
extension OpaquePointer {
999999
@_transparent
1000-
public init(_ from: UnsafeMutableRawPointer) {
1000+
public init(@_nonEphemeral _ from: UnsafeMutableRawPointer) {
10011001
self._rawValue = from._rawValue
10021002
}
10031003

10041004
@_transparent
1005-
public init?(_ from: UnsafeMutableRawPointer?) {
1005+
public init?(@_nonEphemeral _ from: UnsafeMutableRawPointer?) {
10061006
guard let unwrapped = from else { return nil }
10071007
self._rawValue = unwrapped._rawValue
10081008
}
10091009

10101010
@_transparent
1011-
public init(_ from: UnsafeRawPointer) {
1011+
public init(@_nonEphemeral _ from: UnsafeRawPointer) {
10121012
self._rawValue = from._rawValue
10131013
}
10141014

10151015
@_transparent
1016-
public init?(_ from: UnsafeRawPointer?) {
1016+
public init?(@_nonEphemeral _ from: UnsafeRawPointer?) {
10171017
guard let unwrapped = from else { return nil }
10181018
self._rawValue = unwrapped._rawValue
10191019
}

test/Constraints/valid_pointer_conversions.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ func foo(_ a: [[UInt8]], _ p: [UnsafeRawPointer]) {
88
func takesPtr(_: UnsafePointer<UInt8>) {}
99

1010
func givesPtr(_ str: String) {
11-
takesPtr(UnsafePointer(str))
11+
takesPtr(UnsafePointer(str)) // expected-warning {{initialization of 'UnsafePointer<UInt8>' results in a dangling pointer}}
12+
// expected-note @-1 {{implicit argument conversion from 'String' to 'UnsafePointer<UInt8>' produces a pointer valid only for the duration of the call to 'init(_:)'}}
13+
// expected-note@-2 {{use the 'withCString' method on String in order to explicitly convert argument to pointer valid for a defined scope}}
1214
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-typecheck-verify-swift -diagnose-invalid-ephemeralness-as-error
2+
// REQUIRES: objc_interop
3+
4+
func unsafePointerInitEphemeralConversions() {
5+
class C {}
6+
var c: C?
7+
8+
_ = AutoreleasingUnsafeMutablePointer(&c) // expected-error {{initialization of 'AutoreleasingUnsafeMutablePointer<C?>' results in a dangling pointer}}
9+
// expected-note@-1 {{implicit argument conversion from 'C?' to 'AutoreleasingUnsafeMutablePointer<C?>' produces a pointer valid only for the duration of the call to 'init(_:)'}}
10+
}

0 commit comments

Comments
 (0)