Skip to content

Commit ece0951

Browse files
authored
Migrate from UnsafePointer<Void> to UnsafeRawPointer. (#3724)
* Migrate from `UnsafePointer<Void>` to `UnsafeRawPointer`. As proposed in SE-0107: UnsafeRawPointer. `void*` imports as `UnsafeMutableRawPointer`. `const void*` imports as `UnsafeRawPointer`. Occurrences of `UnsafePointer<Void>` are replaced with UnsafeRawPointer. * Migrate overlays from UnsafePointer<Void> to UnsafeRawPointer. This requires explicit memory binding in several places, particularly in NSData and CoreAudio. * Fix a bunch of test cases for Void->Raw migration. * qsort takes IUO values * Bridge `Unsafe[Mutable]RawPointer as `void [const] *`. * Parse #dsohandle as UnsafeMutableRawPointer * Update a bunch of test cases for Void->Raw migration. * Trivial fix for the SceneKit test case. * Add an UnsafeRawPointer self initializer. This is unfortunately necessary for assignment between types imported from C. * Tiny simplification of the initializer.
1 parent 3b03d45 commit ece0951

File tree

74 files changed

+339
-307
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+339
-307
lines changed

benchmark/utils/DriverUtils.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,9 @@ func internalMedian(_ inputs: [UInt64]) -> UInt64 {
220220
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
221221

222222
@_silgen_name("swift_leaks_startTrackingObjects")
223-
func startTrackingObjects(_: UnsafeMutablePointer<Void>) -> ()
223+
func startTrackingObjects(_: UnsafeMutableRawPointer) -> ()
224224
@_silgen_name("swift_leaks_stopTrackingObjects")
225-
func stopTrackingObjects(_: UnsafeMutablePointer<Void>) -> Int
225+
func stopTrackingObjects(_: UnsafeMutableRawPointer) -> Int
226226

227227
#endif
228228

@@ -235,14 +235,14 @@ class SampleRunner {
235235
// Start the timer.
236236
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
237237
var str = name
238-
startTrackingObjects(UnsafeMutablePointer<Void>(str._core.startASCII))
238+
startTrackingObjects(UnsafeMutableRawPointer(str._core.startASCII))
239239
#endif
240240
let start_ticks = mach_absolute_time()
241241
fn(Int(num_iters))
242242
// Stop the timer.
243243
let end_ticks = mach_absolute_time()
244244
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
245-
stopTrackingObjects(UnsafeMutablePointer<Void>(str._core.startASCII))
245+
stopTrackingObjects(UnsafeMutableRawPointer(str._core.startASCII))
246246
#endif
247247

248248
// Compute the spent time and the scaling factor.

docs/proposals/CPointerInteropLanguageModel.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ accept any of the following:
6161
array, and lifetime-extended for the duration of the callee.
6262

6363
As a special case, when a function is declared as taking an
64-
``UnsafeMutablePointer<Void>`` argument, it can accept the same operands as
64+
``UnsafeMutableRawPointer`` argument, it can accept the same operands as
6565
``UnsafeMutablePointer<T>`` for any type T.
6666

6767
So if you have a function declared::
@@ -80,7 +80,7 @@ You can call it as any of::
8080

8181
And if you have a function declared::
8282

83-
func bar(_ x: UnsafeMutablePointer<Void>)
83+
func bar(_ x: UnsafeMutableRawPointer)
8484

8585
You can call it as any of::
8686

@@ -139,7 +139,7 @@ accept any of the following:
139139
array, and lifetime-extended for the duration of the callee.
140140

141141
As a special case, when a function is declared as taking an
142-
``UnsafePointer<Void>`` argument, it can accept the same operands as
142+
``UnsafeRawPointer`` argument, it can accept the same operands as
143143
``UnsafePointer<T>`` for any type ``T``. Pointers to certain integer
144144
types can furthermore interoperate with strings; see `Strings`_ below.
145145

@@ -158,7 +158,7 @@ You can call it as any of::
158158

159159
And if you have a function declared::
160160

161-
func zang(_ x: UnsafePointer<Void>)
161+
func zang(_ x: UnsafeRawPointer)
162162

163163
You can call it as any of::
164164

@@ -175,7 +175,7 @@ You can call it as any of::
175175
zang(ints)
176176

177177
A type checker limitation prevents array literals from being passed directly
178-
to ``UnsafePointer<Void>`` arguments without type annotation. As a
178+
to ``UnsafeRawPointer`` arguments without type annotation. As a
179179
workaround, you can bind the array literal to a constant, as above, or
180180
specify the array type with ``as``::
181181

lib/AST/Module.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -371,23 +371,16 @@ VarDecl *Module::getDSOHandle() {
371371
if (DSOHandle)
372372
return DSOHandle;
373373

374-
auto unsafeMutablePtr = getASTContext().getUnsafeMutablePointerDecl();
375-
if (!unsafeMutablePtr)
374+
auto unsafeMutableRawPtr = getASTContext().getUnsafeMutableRawPointerDecl();
375+
if (!unsafeMutableRawPtr)
376376
return nullptr;
377377

378-
Type arg;
379378
auto &ctx = getASTContext();
380-
if (auto voidDecl = ctx.getVoidDecl()) {
381-
arg = voidDecl->getDeclaredInterfaceType();
382-
} else {
383-
arg = TupleType::getEmpty(ctx);
384-
}
385-
386-
Type type = BoundGenericType::get(unsafeMutablePtr, Type(), { arg });
387379
auto handleVar = new (ctx) VarDecl(/*IsStatic=*/false, /*IsLet=*/false,
388380
SourceLoc(),
389381
ctx.getIdentifier("__dso_handle"),
390-
type, Files[0]);
382+
unsafeMutableRawPtr->getDeclaredType(),
383+
Files[0]);
391384
handleVar->setImplicit(true);
392385
handleVar->getAttrs().add(
393386
new (ctx) SILGenNameAttr("__dso_handle", /*Implicit=*/true));

lib/ClangImporter/ImportType.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ namespace {
287287

288288
ImportResult VisitPointerType(const clang::PointerType *type) {
289289
auto pointeeQualType = type->getPointeeType();
290+
auto quals = pointeeQualType.getQualifiers();
290291

291292
// Special case for NSZone*, which has its own Swift wrapper.
292293
if (const clang::RecordType *pointee =
@@ -303,7 +304,19 @@ namespace {
303304
return {wrapperTy, ImportHint::OtherPointer};
304305
}
305306
}
306-
307+
308+
// Import 'void*' as 'UnsafeMutableRawPointer' and 'const void*' as
309+
// 'UnsafeRawPointer'. This is Swift's version of an untyped pointer. Note
310+
// that 'Unsafe[Mutable]Pointer<T>' implicitly converts to
311+
// 'Unsafe[Mutable]RawPointer' for interoperability.
312+
if (pointeeQualType->isVoidType()) {
313+
return {
314+
(quals.hasConst() ? Impl.SwiftContext.getUnsafeRawPointerDecl()
315+
: Impl.SwiftContext.getUnsafeMutableRawPointerDecl())
316+
->getDeclaredType(),
317+
ImportHint::OtherPointer};
318+
}
319+
307320
// All other C pointers to concrete types map to
308321
// UnsafeMutablePointer<T> or OpaquePointer (FIXME:, except in
309322
// parameter position under the pre-
@@ -336,8 +349,6 @@ namespace {
336349
};
337350
}
338351

339-
auto quals = pointeeQualType.getQualifiers();
340-
341352
if (quals.hasConst()) {
342353
return {Impl.getNamedSwiftTypeSpecialization(Impl.getStdlibModule(),
343354
"UnsafePointer",

lib/IDE/CodeCompletion.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4656,7 +4656,7 @@ static void addExprKeywords(CodeCompletionResultSink &Sink) {
46564656
// Same: Swift.IntegerLiteralType.
46574657
AddKeyword("#line", "Int", CodeCompletionKeywordKind::pound_line);
46584658
AddKeyword("#column", "Int", CodeCompletionKeywordKind::pound_column);
4659-
AddKeyword("#dsohandle", "UnsafeMutablePointer<Void>", CodeCompletionKeywordKind::pound_dsohandle);
4659+
AddKeyword("#dsohandle", "UnsafeMutableRawPointer", CodeCompletionKeywordKind::pound_dsohandle);
46604660
}
46614661

46624662
static void addAnyTypeKeyword(CodeCompletionResultSink &Sink) {

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,8 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
949949
MAP(Bool, "BOOL", false);
950950

951951
MAP(OpaquePointer, "void *", true);
952+
MAP(UnsafeRawPointer, "void const *", true);
953+
MAP(UnsafeMutableRawPointer, "void *", true);
952954

953955
Identifier ID_ObjectiveC = ctx.Id_ObjectiveC;
954956
specialNames[{ID_ObjectiveC, ctx.getIdentifier("ObjCBool")}]

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,7 @@ namespace {
12271227
return visitLiteralExpr(expr);
12281228

12291229
case MagicIdentifierLiteralExpr::DSOHandle: {
1230-
// #dsohandle has type UnsafeMutablePointer<Void>.
1230+
// #dsohandle has type UnsafeMutableRawPointer.
12311231
auto &tc = CS.getTypeChecker();
12321232
if (tc.requirePointerArgumentIntrinsics(expr->getLoc()))
12331233
return nullptr;

stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ internal class PthreadBlockContext {
2727
/// Execute the block, and return an `UnsafeMutablePointer` to memory
2828
/// allocated with `UnsafeMutablePointer.alloc` containing the result of the
2929
/// block.
30-
func run() -> UnsafeMutablePointer<Void> { fatalError("abstract") }
30+
func run() -> UnsafeMutableRawPointer { fatalError("abstract") }
3131
}
3232

3333
internal class PthreadBlockContextImpl<Argument, Result>: PthreadBlockContext {
@@ -40,17 +40,17 @@ internal class PthreadBlockContextImpl<Argument, Result>: PthreadBlockContext {
4040
super.init()
4141
}
4242

43-
override func run() -> UnsafeMutablePointer<Void> {
43+
override func run() -> UnsafeMutableRawPointer {
4444
let result = UnsafeMutablePointer<Result>.allocate(capacity: 1)
4545
result.initialize(to: block(arg))
46-
return UnsafeMutablePointer(result)
46+
return UnsafeMutableRawPointer(result)
4747
}
4848
}
4949

5050
/// Entry point for `pthread_create` that invokes a block context.
5151
internal func invokeBlockContext(
52-
_ contextAsVoidPointer: UnsafeMutablePointer<Void>?
53-
) -> UnsafeMutablePointer<Void>! {
52+
_ contextAsVoidPointer: UnsafeMutableRawPointer?
53+
) -> UnsafeMutableRawPointer! {
5454
// The context is passed in +1; we're responsible for releasing it.
5555
let context = Unmanaged<PthreadBlockContext>
5656
.fromOpaque(contextAsVoidPointer!)
@@ -95,12 +95,14 @@ public func _stdlib_pthread_join<Result>(
9595
_ thread: pthread_t,
9696
_ resultType: Result.Type
9797
) -> (CInt, Result?) {
98-
var threadResultPtr: UnsafeMutablePointer<Void>? = nil
99-
let result = pthread_join(thread, &threadResultPtr)
98+
var threadResultRawPtr: UnsafeMutableRawPointer? = nil
99+
let result = pthread_join(thread, &threadResultRawPtr)
100100
if result == 0 {
101-
let threadResult = UnsafeMutablePointer<Result>(threadResultPtr!).pointee
102-
threadResultPtr!.deinitialize()
103-
threadResultPtr!.deallocate(capacity: 1)
101+
let threadResultPtr = threadResultRawPtr!.assumingMemoryBound(
102+
to: Result.self)
103+
let threadResult = threadResultPtr.pointee
104+
threadResultPtr.deinitialize()
105+
threadResultPtr.deallocate(capacity: 1)
104106
return (result, threadResult)
105107
} else {
106108
return (result, nil)

stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public enum InstanceKind : UInt8 {
4848
/// Represents a section in a loaded image in this process.
4949
internal struct Section {
5050
/// The absolute start address of the section's data in this address space.
51-
let startAddress: UnsafePointer<Void>
51+
let startAddress: UnsafeRawPointer
5252

5353
/// The size of the section in bytes.
5454
let size: UInt
@@ -211,7 +211,7 @@ internal func sendBytes() {
211211
let count = Int(readUInt())
212212
debugLog("Parent requested \(count) bytes from \(address)")
213213
var totalBytesWritten = 0
214-
var pointer = unsafeBitCast(address, to: UnsafeMutablePointer<Void>.self)
214+
var pointer = unsafeBitCast(address, to: UnsafeMutableRawPointer.self)
215215
while totalBytesWritten < count {
216216
let bytesWritten = Int(fwrite(pointer, 1, Int(count), stdout))
217217
fflush(stdout)
@@ -228,7 +228,7 @@ internal func sendSymbolAddress() {
228228
debugLog("BEGIN \(#function)"); defer { debugLog("END \(#function)") }
229229
let name = readLine()!
230230
name.withCString {
231-
let handle = unsafeBitCast(Int(-2), to: UnsafeMutablePointer<Void>.self)
231+
let handle = unsafeBitCast(Int(-2), to: UnsafeMutableRawPointer.self)
232232
let symbol = dlsym(handle, $0)
233233
let symbolAddress = unsafeBitCast(symbol, to: UInt.self)
234234
sendValue(symbolAddress)
@@ -247,7 +247,7 @@ internal func sendStringLength() {
247247
/// Send the size of this architecture's pointer type.
248248
internal func sendPointerSize() {
249249
debugLog("BEGIN \(#function)"); defer { debugLog("END \(#function)") }
250-
let pointerSize = UInt8(sizeof(UnsafePointer<Void>.self))
250+
let pointerSize = UInt8(sizeof(UnsafeRawPointer.self))
251251
sendValue(pointerSize)
252252
}
253253

@@ -412,8 +412,8 @@ struct ThickFunction3 {
412412
}
413413

414414
struct ThickFunctionParts {
415-
var function: UnsafePointer<Void>
416-
var context: Optional<UnsafePointer<Void>>
415+
var function: UnsafeRawPointer
416+
var context: Optional<UnsafeRawPointer>
417417
}
418418

419419
/// Reflect a closure context. The given function must be a Swift-native

stdlib/public/Platform/Platform.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ internal func _swift_Platform_fcntl(
219219
internal func _swift_Platform_fcntlPtr(
220220
_ fd: Int32,
221221
_ cmd: Int32,
222-
_ ptr: UnsafeMutablePointer<Void>
222+
_ ptr: UnsafeMutableRawPointer
223223
) -> Int32
224224

225225
public func fcntl(
@@ -240,7 +240,7 @@ public func fcntl(
240240
public func fcntl(
241241
_ fd: Int32,
242242
_ cmd: Int32,
243-
_ ptr: UnsafeMutablePointer<Void>
243+
_ ptr: UnsafeMutableRawPointer
244244
) -> Int32 {
245245
return _swift_Platform_fcntlPtr(fd, cmd, ptr)
246246
}
@@ -313,7 +313,7 @@ internal func _swift_Platform_ioctl(
313313
internal func _swift_Platform_ioctlPtr(
314314
_ fd: CInt,
315315
_ request: UInt,
316-
_ ptr: UnsafeMutablePointer<Void>
316+
_ ptr: UnsafeMutableRawPointer
317317
) -> CInt
318318

319319
public func ioctl(
@@ -327,7 +327,7 @@ public func ioctl(
327327
public func ioctl(
328328
_ fd: CInt,
329329
_ request: UInt,
330-
_ ptr: UnsafeMutablePointer<Void>
330+
_ ptr: UnsafeMutableRawPointer
331331
) -> CInt {
332332
return _swift_Platform_ioctlPtr(fd, request, ptr)
333333
}

stdlib/public/SDK/CoreAudio/CoreAudio.swift

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,23 @@
1414

1515
extension UnsafeBufferPointer {
1616
/// Initialize an `UnsafeBufferPointer<Element>` from an `AudioBuffer`.
17+
/// Binds the the buffer's memory type to `Element`.
1718
public init(_ audioBuffer: AudioBuffer) {
18-
self.init(
19-
start: UnsafePointer<Element>(audioBuffer.mData),
20-
count: Int(audioBuffer.mDataByteSize) / strideof(Element.self))
19+
let count = Int(audioBuffer.mDataByteSize) / strideof(Element.self)
20+
let elementPtr = audioBuffer.mData?.bindMemory(
21+
to: Element.self, capacity: count)
22+
self.init(start: elementPtr, count: count)
2123
}
2224
}
2325

2426
extension UnsafeMutableBufferPointer {
2527
/// Initialize an `UnsafeMutableBufferPointer<Element>` from an
2628
/// `AudioBuffer`.
2729
public init(_ audioBuffer: AudioBuffer) {
28-
self.init(
29-
start: UnsafeMutablePointer<Element>(audioBuffer.mData),
30-
count: Int(audioBuffer.mDataByteSize) / strideof(Element.self))
30+
let count = Int(audioBuffer.mDataByteSize) / strideof(Element.self)
31+
let elementPtr = audioBuffer.mData?.bindMemory(
32+
to: Element.self, capacity: count)
33+
self.init(start: elementPtr, count: count)
3134
}
3235
}
3336

@@ -39,7 +42,7 @@ extension AudioBuffer {
3942
numberOfChannels: Int
4043
) {
4144
self.mNumberChannels = UInt32(numberOfChannels)
42-
self.mData = UnsafeMutablePointer<Void>(typedBuffer.baseAddress)
45+
self.mData = UnsafeMutableRawPointer(typedBuffer.baseAddress)
4346
self.mDataByteSize = UInt32(typedBuffer.count * strideof(Element.self))
4447
}
4548
}
@@ -68,8 +71,10 @@ extension AudioBufferList {
6871
_precondition(ablMemory != nil,
6972
"failed to allocate memory for an AudioBufferList")
7073

71-
let abl = UnsafeMutableAudioBufferListPointer(
72-
UnsafeMutablePointer<AudioBufferList>(ablMemory!))
74+
let listPtr = ablMemory!.bindMemory(to: AudioBufferList.self, capacity: 1)
75+
(ablMemory! + strideof(AudioBufferList.self)).bindMemory(
76+
to: AudioBuffer.self, capacity: maximumBuffers)
77+
let abl = UnsafeMutableAudioBufferListPointer(listPtr)
7378
abl.count = maximumBuffers
7479
return abl
7580
}
@@ -108,7 +113,8 @@ public struct UnsafeMutableAudioBufferListPointer {
108113
// AudioBufferList has one AudioBuffer in a "flexible array member".
109114
// Position the pointer after that, and skip one AudioBuffer back. This
110115
// brings us to the start of AudioBuffer array.
111-
return UnsafeMutablePointer<AudioBuffer>(unsafeMutablePointer + 1) - 1
116+
let rawPtr = UnsafeMutableRawPointer(unsafeMutablePointer + 1)
117+
return rawPtr.assumingMemoryBound(to: AudioBuffer.self) - 1
112118
}
113119

114120
// FIXME: the properties 'unsafePointer' and 'unsafeMutablePointer' should be

0 commit comments

Comments
 (0)