// RUN: rm -rf %t && mkdir -p %t && %S/../../utils/gyb %s -o %t/UnsafePointer.swift // RUN: %S/../../utils/line-directive %t/UnsafePointer.swift -- %target-build-swift %t/UnsafePointer.swift -o %t/a.out // RUN: %S/../../utils/line-directive %t/UnsafePointer.swift -- %target-run %t/a.out // REQUIRES: executable_test import StdlibUnittest // Also import modules which are used by StdlibUnittest internally. This // workaround is needed to link all required libraries in case we compile // StdlibUnittest with -sil-serialize-all. import SwiftPrivate #if _runtime(_ObjC) import ObjectiveC #endif protocol TestProtocol1 {} // Check that the generic parameter is called 'Pointee'. #if _runtime(_ObjC) extension AutoreleasingUnsafeMutablePointer where Pointee : TestProtocol1 { var _memoryIsTestProtocol1: Bool { fatalError("not implemented") } } #endif extension UnsafePointer where Pointee : TestProtocol1 { var _memoryIsTestProtocol1: Bool { fatalError("not implemented") } } extension UnsafeMutablePointer where Pointee : TestProtocol1 { var _memoryIsTestProtocol1: Bool { fatalError("not implemented") } } // Check that the generic parameter is called 'Element'. extension UnsafeBufferPointerIterator where Element : TestProtocol1 { var _elementIsTestProtocol1: Bool { fatalError("not implemented") } } extension UnsafeBufferPointer where Element : TestProtocol1 { var _elementIsTestProtocol1: Bool { fatalError("not implemented") } } extension UnsafeMutableBufferPointer where Element : TestProtocol1 { var _elementIsTestProtocol1: Bool { fatalError("not implemented") } } var UnsafePointerTestSuite = TestSuite("UnsafePointer") var UnsafeMutablePointerTestSuite = TestSuite("UnsafeMutablePointer") var OpaquePointerTestSuite = TestSuite("OpaquePointer") % for (SelfName, SelfType) in [ % ('UnsafePointer', 'UnsafePointer'), % ('UnsafeMutablePointer', 'UnsafeMutablePointer'), % ('OpaquePointer', 'OpaquePointer')]: ${SelfName}TestSuite.test("convertFromNil") { let ptr: ${SelfType} = nil expectEqual(0, unsafeBitCast(ptr, to: Int.self)) } ${SelfName}TestSuite.test("initNoArgs") { let ptr: ${SelfType} = nil expectEqual(0, unsafeBitCast(ptr, to: Int.self)) } ${SelfName}TestSuite.test("initFromOpaquePointer") { let other = OpaquePointer(bitPattern: 0x12345678) let ptr = UnsafePointer(other) expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self)) } ${SelfName}TestSuite.test("initFromUnsafePointer") { let other = UnsafePointer(bitPattern: 0x12345678) let ptr = ${SelfType}(other) expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self)) } ${SelfName}TestSuite.test("initFromUnsafeMutablePointer") { let other = UnsafeMutablePointer(bitPattern: 0x12345678) let ptr = ${SelfType}(other) expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self)) } ${SelfName}TestSuite.test("initFromInteger") { if true { let word: Int = 0x12345678 let ptr = ${SelfType}(bitPattern: word) expectEqual(word, unsafeBitCast(ptr, to: Int.self)) } if true { let uword: UInt = 0x12345678 let ptr = ${SelfType}(bitPattern: uword) expectEqual(uword, unsafeBitCast(ptr, to: UInt.self)) } } ${SelfName}TestSuite.test("Hashable") { let ptrs = [ ${SelfType}(bitPattern: 0x0), ${SelfType}(bitPattern: 0x12345678), ${SelfType}(bitPattern: 0x87654321 as UInt), ] for i in ptrs.indices { for j in ptrs.indices { var pi = ptrs[i] var pj = ptrs[j] checkHashable(i == j, pi, pj, "i=\(i), j=\(j)") } } } % end enum Check { case LeftOverlap case RightOverlap case Disjoint } class Missile { static var missilesLaunched = 0 let number: Int init(_ number: Int) { self.number = number } deinit { Missile.missilesLaunched += 1 } } func checkPointerCorrectness(check: Check, _ f: (UnsafeMutablePointer) -> (UnsafeMutablePointer, count: Int) -> Void, _ withMissiles: Bool = false) { let ptr = UnsafeMutablePointer(allocatingCapacity: 4) switch check { case .RightOverlap: ptr.initialize(with: Missile(1)) (ptr + 1).initialize(with: Missile(2)) if withMissiles { (ptr + 2).initialize(with: Missile(3)) } f(ptr + 1)(ptr, count: 2) expectEqual(1, ptr[1].number) expectEqual(2, ptr[2].number) case .LeftOverlap: if withMissiles { ptr.initialize(with: Missile(1)) } (ptr + 1).initialize(with: Missile(2)) (ptr + 2).initialize(with: Missile(3)) f(ptr)(ptr + 1, count: 2) expectEqual(2, ptr[0].number) expectEqual(3, ptr[1].number) case .Disjoint: if withMissiles { ptr.initialize(with: Missile(0)) (ptr + 1).initialize(with: Missile(1)) } (ptr + 2).initialize(with: Missile(2)) (ptr + 3).initialize(with: Missile(3)) f(ptr)(ptr + 2, count: 2) expectEqual(2, ptr[0].number) expectEqual(3, ptr[1].number) // backwards let ptr2 = UnsafeMutablePointer(allocatingCapacity: 4) ptr2.initialize(with: Missile(0)) (ptr2 + 1).initialize(with: Missile(1)) if withMissiles { (ptr2 + 2).initialize(with: Missile(2)) (ptr2 + 3).initialize(with: Missile(3)) } f(ptr2 + 2)(ptr2, count: 2) expectEqual(0, ptr2[2].number) expectEqual(1, ptr2[3].number) } } let checkPtr: ((UnsafeMutablePointer -> (UnsafeMutablePointer, count: Int) -> Void), Bool) -> Check -> Void = { (f, m) in return { checkPointerCorrectness($0, f, m) } } UnsafeMutablePointerTestSuite.test("moveInitializeBackwardFrom") { let check = checkPtr(UnsafeMutablePointer.moveInitializeBackwardFrom, false) check(Check.RightOverlap) check(Check.Disjoint) // This check relies on _stdlibAssert() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.LeftOverlap) } } UnsafeMutablePointerTestSuite.test("moveAssignFrom") { let check = checkPtr(UnsafeMutablePointer.moveAssignFrom, true) check(Check.Disjoint) // This check relies on _stdlibAssert() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.LeftOverlap) } } UnsafeMutablePointerTestSuite.test("moveAssignFrom.Right") { let check = checkPtr(UnsafeMutablePointer.moveAssignFrom, true) // This check relies on _stdlibAssert() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.RightOverlap) } } UnsafeMutablePointerTestSuite.test("assignFrom") { let check = checkPtr(UnsafeMutablePointer.assignFrom, true) check(Check.LeftOverlap) check(Check.Disjoint) // This check relies on _stdlibAssert() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.RightOverlap) } } UnsafeMutablePointerTestSuite.test("assignBackwardFrom") { let check = checkPtr(UnsafeMutablePointer.assignBackwardFrom, true) check(Check.RightOverlap) check(Check.Disjoint) // This check relies on _stdlibAssert() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.LeftOverlap) } } UnsafeMutablePointerTestSuite.test("moveInitializeFrom") { let check = checkPtr(UnsafeMutablePointer.moveInitializeFrom, false) check(Check.LeftOverlap) check(Check.Disjoint) // This check relies on _stdlibAssert() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.RightOverlap) } } UnsafeMutablePointerTestSuite.test("initializeFrom") { let check = checkPtr(UnsafeMutablePointer.initializeFrom, false) check(Check.Disjoint) // This check relies on _stdlibAssert() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.LeftOverlap) } } UnsafeMutablePointerTestSuite.test("initializeFrom.Right") { let check = checkPtr(UnsafeMutablePointer.initializeFrom, false) // This check relies on _stdlibAssert() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.RightOverlap) } } UnsafePointerTestSuite.test("customMirror") { // Ensure that the custom mirror works properly, including when the raw value // is greater than Int.max let reallyBigInt: UInt = UInt(Int.max) + 1 let ptr = UnsafePointer(bitPattern: reallyBigInt) let mirror = ptr.customMirror expectEqual(1, mirror.children.count) #if arch(i386) || arch(arm) expectEqual("18446744071562067968", String(mirror.children.first!.1)) #elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) expectEqual("9223372036854775808", String(mirror.children.first!.1)) #else fatalError("Unimplemented") #endif } UnsafePointerTestSuite.test("customPlaygroundQuickLook") { // Ensure that the custom playground quicklook works properly, including when // the raw value is greater than Int.max let reallyBigInt: UInt = UInt(Int.max) + 1 let ptr = UnsafePointer(bitPattern: reallyBigInt) if case let .text(desc) = ptr.customPlaygroundQuickLook { #if arch(i386) || arch(arm) expectEqual("UnsafePointer(0xFFFFFFFF80000000)", desc) #elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) expectEqual("UnsafePointer(0x8000000000000000)", desc) #else fatalError("Unimplemented") #endif } else { expectTrue(false) } } UnsafeMutablePointerTestSuite.test("customMirror") { let reallyBigInt: UInt = UInt(Int.max) + 1 let ptr = UnsafeMutablePointer(bitPattern: reallyBigInt) let mirror = ptr.customMirror expectEqual(1, mirror.children.count) #if arch(i386) || arch(arm) expectEqual("18446744071562067968", String(mirror.children.first!.1)) #elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) expectEqual("9223372036854775808", String(mirror.children.first!.1)) #else fatalError("Unimplemented") #endif } UnsafeMutablePointerTestSuite.test("customPlaygroundQuickLook") { let reallyBigInt: UInt = UInt(Int.max) + 1 let ptr = UnsafeMutablePointer(bitPattern: reallyBigInt) let isProperDisposition : Bool if case let .text(desc) = ptr.customPlaygroundQuickLook { #if arch(i386) || arch(arm) expectEqual("UnsafeMutablePointer(0xFFFFFFFF80000000)", desc) #elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) expectEqual("UnsafeMutablePointer(0x8000000000000000)", desc) #else fatalError("Unimplemented") #endif } else { expectTrue(false) } } runAllTests()