// RUN: %target-run-simple-swiftgyb // REQUIRES: executable_test // REQUIRES: reflection import StdlibUnittest 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 UnsafeBufferPointer.Iterator 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 UnsafeRawPointerTestSuite = TestSuite("UnsafeRawPointer") var UnsafeMutableRawPointerTestSuite = TestSuite("UnsafeMutableRawPointer") var OpaquePointerTestSuite = TestSuite("OpaquePointer") % for (SelfName, SelfType) in [ % ('UnsafePointer', 'UnsafePointer'), % ('UnsafeMutablePointer', 'UnsafeMutablePointer'), % ('UnsafeRawPointer', 'UnsafeRawPointer'), % ('UnsafeMutableRawPointer', 'UnsafeMutableRawPointer')]: ${SelfName}TestSuite.test("initFromOpaquePointer") { let other = OpaquePointer(bitPattern: 0x12345678)! let ptr = ${SelfType}(other) expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self)) let optionalOther: Optional = other let optionalPointer = ${SelfType}(optionalOther) expectNotNil(optionalPointer) expectEqual(0x12345678, unsafeBitCast(optionalPointer, to: Int.self)) let nilOther: Optional = nil let nilPointer = ${SelfType}(nilOther) expectNil(nilPointer) } % end % for (SelfName, SelfType) in [ % ('UnsafeRawPointer', 'UnsafeRawPointer'), % ('UnsafeMutableRawPointer', 'UnsafeMutableRawPointer')]: UnsafeMutableRawPointerTestSuite.test("initFromMutating") { let other = UnsafeRawPointer(bitPattern: 0x12345678)! let ptr = UnsafeMutableRawPointer(mutating: other) expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self)) let optionalOther: Optional = other let optionalPointer = UnsafeMutableRawPointer(mutating: optionalOther) expectNotNil(optionalPointer) expectEqual(0x12345678, unsafeBitCast(optionalPointer, to: Int.self)) let nilOther: Optional = nil let nilPointer = UnsafeMutableRawPointer(mutating: nilOther) expectNil(nilPointer) } % end % for (SelfName, SelfType) in [ % ('UnsafePointer', 'UnsafePointer'), % ('UnsafeMutablePointer', 'UnsafeMutablePointer'), % ('UnsafeRawPointer', 'UnsafeRawPointer'), % ('UnsafeMutableRawPointer', 'UnsafeMutableRawPointer'), % ('OpaquePointer', 'OpaquePointer')]: ${SelfName}TestSuite.test("convertFromNil") { let ptr: ${SelfType}? = nil expectEqual(0, unsafeBitCast(ptr, to: Int.self)) } ${SelfName}TestSuite.test("initFromInteger") { do { let word: Int = 0x12345678 let ptr = ${SelfType}(bitPattern: word) expectNotNil(ptr) expectEqual(word, unsafeBitCast(ptr, to: Int.self)) } do { let uword: UInt = 0x12345678 let ptr = ${SelfType}(bitPattern: uword) expectNotNil(ptr) expectEqual(uword, unsafeBitCast(ptr, to: UInt.self)) } } ${SelfName}TestSuite.test("initFromNilBitPattern") { do { let word = unsafeBitCast(nil as ${SelfType}?, to: Int.self) let ptr = ${SelfType}(bitPattern: word) expectNil(ptr) expectEqual(word, unsafeBitCast(ptr, to: Int.self)) } do { let uword = unsafeBitCast(nil as ${SelfType}?, to: UInt.self) let ptr = ${SelfType}(bitPattern: uword) expectNil(ptr) expectEqual(uword, unsafeBitCast(ptr, to: UInt.self)) } } ${SelfName}TestSuite.test("Hashable") { let ptrs = [ ${SelfType}(bitPattern: 0x12345678)!, ${SelfType}(bitPattern: 0x87654321 as UInt)!, ] checkHashable(ptrs, equalityOracle: { $0 == $1 }) } ${SelfName}TestSuite.test("toInteger") { do { let word: Int = 0x12345678 let ptr = ${SelfType}(bitPattern: word) expectEqual(word, Int(bitPattern: ptr)) } do { let ptr: ${SelfType}? = nil expectEqual(Int(0), Int(bitPattern: ptr)) } do { let uword: UInt = 0x12345678 let ptr = ${SelfType}(bitPattern: uword) expectEqual(uword, UInt(bitPattern: ptr)) } do { let ptr: ${SelfType}? = nil expectEqual(UInt(0), UInt(bitPattern: ptr)) } } % end % for (SelfName, SelfType) in [ % ('UnsafePointer', 'UnsafePointer'), % ('UnsafeRawPointer', 'UnsafeRawPointer'), % ('UnsafeMutableRawPointer', 'UnsafeMutableRawPointer')]: ${SelfName}TestSuite.test("initFromUnsafeMutablePointer") { let other = UnsafeMutablePointer(bitPattern: 0x12345678)! let ptr = ${SelfType}(other) expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self)) let optionalOther: Optional = other let optionalPointer = ${SelfType}(optionalOther) expectNotNil(optionalPointer) expectEqual(0x12345678, unsafeBitCast(optionalPointer, to: Int.self)) let nilOther: Optional> = nil let nilPointer = ${SelfType}(nilOther) expectNil(nilPointer) } % end % for (SelfName, SelfType) in [ % ('UnsafePointer', 'UnsafePointer'), % ('UnsafeRawPointer', 'UnsafeRawPointer')]: ${SelfName}TestSuite.test("initFromUnsafePointer") { let other = UnsafePointer(bitPattern: 0x12345678)! let ptr = ${SelfType}(other) expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self)) let optionalOther: Optional = other let optionalPointer = ${SelfType}(optionalOther) expectNotNil(optionalPointer) expectEqual(0x12345678, unsafeBitCast(optionalPointer, to: Int.self)) let nilOther: Optional> = nil let nilPointer = ${SelfType}(nilOther) expectNil(nilPointer) } % end UnsafeRawPointerTestSuite.test("initFromUnsafeMutableRawPointer") { let other = UnsafeMutableRawPointer(bitPattern: 0x12345678)! let ptr = UnsafeRawPointer(other) expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self)) let optionalOther: Optional = other let optionalPointer = UnsafeRawPointer(optionalOther) expectNotNil(optionalPointer) expectEqual(0x12345678, unsafeBitCast(optionalPointer, to: Int.self)) let nilOther: Optional = nil let nilPointer = UnsafeRawPointer(nilOther) expectNil(nilPointer) } 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, _ withMissiles: Bool = false, _ f: (UnsafeMutablePointer) -> (UnsafeMutablePointer, _ count: Int) -> Void) { let ptr = UnsafeMutablePointer.allocate(capacity: 4) switch check { case .RightOverlap: ptr.initialize(to: Missile(1)) (ptr + 1).initialize(to: Missile(2)) if withMissiles { (ptr + 2).initialize(to: Missile(3)) } f(ptr + 1)(ptr, 2) expectEqual(1, ptr[1].number) expectEqual(2, ptr[2].number) case .LeftOverlap: if withMissiles { ptr.initialize(to: Missile(1)) } (ptr + 1).initialize(to: Missile(2)) (ptr + 2).initialize(to: Missile(3)) f(ptr)(ptr + 1, 2) expectEqual(2, ptr[0].number) expectEqual(3, ptr[1].number) case .Disjoint: if withMissiles { ptr.initialize(to: Missile(0)) (ptr + 1).initialize(to: Missile(1)) } (ptr + 2).initialize(to: Missile(2)) (ptr + 3).initialize(to: Missile(3)) f(ptr)(ptr + 2, 2) expectEqual(2, ptr[0].number) expectEqual(3, ptr[1].number) // backwards let ptr2 = UnsafeMutablePointer.allocate(capacity: 4) ptr2.initialize(to: Missile(0)) (ptr2 + 1).initialize(to: Missile(1)) if withMissiles { (ptr2 + 2).initialize(to: Missile(2)) (ptr2 + 3).initialize(to: Missile(3)) } f(ptr2 + 2)(ptr2, 2) expectEqual(0, ptr2[2].number) expectEqual(1, ptr2[3].number) } } func checkPtr( _ f: @escaping ((UnsafeMutablePointer) -> (UnsafeMutablePointer, _ count: Int) -> Void), _ m: Bool ) -> (Check) -> Void { return { checkPointerCorrectness($0, m, f) } } func checkPtr( _ f: @escaping ((UnsafeMutablePointer) -> (UnsafePointer, _ count: Int) -> Void), _ m: Bool ) -> (Check) -> Void { return { checkPointerCorrectness($0, m) { destPtr in return { f(destPtr)(UnsafeMutablePointer($0), $1) } } } } #if !os(WASI) // Trap tests aren't available on WASI. UnsafeMutablePointerTestSuite.test("moveAssign:from:") { let check = checkPtr(UnsafeMutablePointer.moveAssign, true) check(Check.Disjoint) // This check relies on _debugPrecondition() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.LeftOverlap) } } UnsafeMutablePointerTestSuite.test("moveAssign:from:.Right") { let check = checkPtr(UnsafeMutablePointer.moveAssign, true) // This check relies on _debugPrecondition() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.RightOverlap) } } #endif UnsafeMutablePointerTestSuite.test("assign:from:") { let check = checkPtr(UnsafeMutablePointer.assign, true) check(Check.LeftOverlap) check(Check.Disjoint) check(Check.RightOverlap) } UnsafeMutablePointerTestSuite.test("moveInitialize:from:") { let check = checkPtr(UnsafeMutablePointer.moveInitialize, false) check(Check.LeftOverlap) check(Check.Disjoint) check(Check.RightOverlap) } #if !os(WASI) // Trap tests aren't available on WASI. UnsafeMutablePointerTestSuite.test("initialize:from:") { let check = checkPtr(UnsafeMutablePointer.initialize(from:count:), false) check(Check.Disjoint) // This check relies on _debugPrecondition() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.LeftOverlap) } } UnsafeMutablePointerTestSuite.test("initialize:from:.Right") { let check = checkPtr(UnsafeMutablePointer.initialize(from:count:), false) // This check relies on _debugPrecondition() so will only trigger in -Onone mode. if _isDebugAssertConfiguration() { expectCrashLater() check(Check.RightOverlap) } } #endif UnsafeMutablePointerTestSuite.test("initialize:from:/immutable") { let ptr = UnsafeMutablePointer.allocate(capacity: 3) defer { ptr.deinitialize(count: 3) ptr.deallocate() } let source = (0..<3).map(Missile.init) source.withUnsafeBufferPointer { bufferPtr in ptr.initialize(from: bufferPtr.baseAddress!, count: 3) expectEqual(0, ptr[0].number) expectEqual(1, ptr[1].number) expectEqual(2, ptr[2].number) } } UnsafeMutablePointerTestSuite.test("assign/immutable") { let ptr = UnsafeMutablePointer.allocate(capacity: 2) defer { ptr.deinitialize(count: 2) ptr.deallocate() } ptr.initialize(to: Missile(1)) (ptr + 1).initialize(to: Missile(2)) let source = (3..<5).map(Missile.init) source.withUnsafeBufferPointer { bufferPtr in ptr.assign(from: bufferPtr.baseAddress!, count: 2) expectEqual(3, ptr[0].number) expectEqual(4, ptr[1].number) } } % for (SelfName, SelfType) in [ % ('UnsafePointer', 'UnsafePointer'), % ('UnsafeMutablePointer', 'UnsafeMutablePointer'), % ('UnsafeRawPointer', 'UnsafeRawPointer'), % ('UnsafeMutableRawPointer', 'UnsafeMutableRawPointer')]: ${SelfName}TestSuite.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 = ${SelfType}(bitPattern: reallyBigInt)! let mirror = ptr.customMirror expectEqual(1, mirror.children.count) #if _pointerBitWidth(_32) expectEqual("18446744071562067968", String(describing: mirror.children.first!.1)) #elseif _pointerBitWidth(_64) expectEqual("9223372036854775808", String(describing: mirror.children.first!.1)) #else fatalError("Unimplemented") #endif } ${SelfName}TestSuite.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 = ${SelfType}(bitPattern: reallyBigInt)! if case let .text(desc) = ptr.customPlaygroundQuickLook { #if _pointerBitWidth(_32) expectEqual("${SelfName}(0xFFFFFFFF80000000)", desc) #elseif _pointerBitWidth(_64) expectEqual("${SelfName}(0x8000000000000000)", desc) #else fatalError("Unimplemented") #endif } else { expectTrue(false) } } ${SelfName}TestSuite.test("Comparable") { var addresses: [UInt] = [ 0x00000001, 0xFF00FF00, 0x00001111, 0x00000002, 0xFFFFFFFF, 0x00001111 ] #if arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) addresses += [ 0xFFFFFFFF80000000, 0x8000000000000000 ] #endif let instances = addresses.map { ($0, ${SelfType}(bitPattern: $0)!) } func comparisonOracle(i: Int, j: Int) -> ExpectedComparisonResult { return instances[i].0 <=> instances[j].0 } checkComparable(instances.map { $0.1 }, oracle: comparisonOracle) } % end % for SelfName in ['UnsafePointer', 'UnsafeMutablePointer']: ${SelfName}TestSuite.test("withMemoryRebound") { let mutablePtrI = UnsafeMutablePointer.allocate(capacity: 4) defer { mutablePtrI.deallocate() } let ptrI = ${SelfName}(mutablePtrI) ptrI.withMemoryRebound(to: UInt.self, capacity: 4) { // Make sure the closure argument isa $SelfName let ptrU: ${SelfName} = $0 // and that the element type is UInt. let mutablePtrU = UnsafeMutablePointer(mutating: ptrU) expectType(UInt.self, &mutablePtrU.pointee) } } ${SelfName}TestSuite.test("withMemoryReboundSE0333") { let mutablePtrI = UnsafeMutablePointer.allocate(capacity: 4) defer { mutablePtrI.deallocate() } let ptrI = ${SelfName}(mutablePtrI) // test rebinding to a wider type with the same alignment ptrI.withMemoryRebound(to: (Int, Int).self, capacity: 2) { // Make sure the closure argument isa $SelfName let ptrT: ${SelfName}<(Int, Int)> = $0 // and that the element type is (Int, Int). let mutablePtrT = UnsafeMutablePointer(mutating: ptrT) expectType((Int, Int).self, &mutablePtrT.pointee) // test rebinding to a narrower type ptrT.withMemoryRebound(to: UInt.self, capacity: 4) { // Make sure the closure argument isa $SelfName let ptrU: ${SelfName} = $0 // and that the element type is UInt. let mutablePtrU = UnsafeMutablePointer(mutating: ptrU) expectType(UInt.self, &mutablePtrU.pointee) } } } ${SelfName}TestSuite.test("withMemoryReboundSE0333.capacity1") { let mutablePtr = UnsafeMutablePointer<(Int,Bool,Int64)>.allocate(capacity: 1) let i = Int.random(in: 0 ... .max) mutablePtr.initialize(to: (i, i.isMultiple(of: 2), Int64(0xff & i))) defer { mutablePtr.deallocate() } let ptr = ${SelfName}<(Int, Bool, Int64)>(mutablePtr) // test rebinding to a shorter type with the same alignment ptr.withMemoryRebound(to: (Int, Bool).self, capacity: 1) { // Make sure the closure argument is a ${SelfName} let ptrT: ${SelfName}<(Int, Bool)> = $0 // and that the element is (Int, Bool). let mutablePtrT = UnsafeMutablePointer(mutating: ptrT) expectType((Int, Bool).self, &mutablePtrT.pointee) expectEqual($0.pointee.0, i) expectEqual($0.pointee.1, i.isMultiple(of: 2)) } } ${SelfName}TestSuite.test("pointer(to:)") { struct Example { var a = false var b = 0 var c: String { "\(a),\(b)" } } let allocated = UnsafeMutablePointer.allocate(capacity: 1) allocated.pointee = Example() defer { allocated.deallocate() } let p = ${SelfName}(allocated) expectEqual(p.pointer(to: \.a)!.pointee, false) expectEqual(p.pointer(to: \.b)!.pointee, 0) expectNil(p.pointer(to: \.c)) % if SelfName == 'UnsafeMutablePointer': p.pointer(to: \.a)!.pointee = true p.pointer(to: \.b)!.pointee += 1 expectEqual(p.pointer(to: \.a as KeyPath)!.pointee, true) expectEqual(p.pointer(to: \.b as KeyPath)!.pointee, 1) % end } #if !os(WASI) ${SelfName}TestSuite.test("pointer(to:).overflow") { struct Example { var a = false var b = 0 var c: String { "\(a),\(b)" } var d = 0.0 } let o = MemoryLayout.offset(of: \.b)! let p = UnsafePointer(bitPattern: -o) expectNotNil(p) guard let p else { fatalError() } if _isDebugAssertConfiguration() { expectCrashLater() } let intPointer = p.pointer(to: \.b) expectNil(intPointer) // nil because of overflow let stringPointer = p.pointer(to: \.c) expectNil(stringPointer) // nil because c is a computed property let doublePointer = p.pointer(to: \.d) expectNotNil(doublePointer) } #endif % end runAllTests()