mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Tacking "Pointee" on just for unary operations (and especially operations with an optional count) created inconsistency.
340 lines
10 KiB
Plaintext
340 lines
10 KiB
Plaintext
// 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<Float>'),
|
|
% ('UnsafeMutablePointer', 'UnsafeMutablePointer<Float>'),
|
|
% ('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<Float>(other)
|
|
expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self))
|
|
}
|
|
|
|
${SelfName}TestSuite.test("initFromUnsafePointer") {
|
|
let other = UnsafePointer<Double>(bitPattern: 0x12345678)
|
|
let ptr = ${SelfType}(other)
|
|
expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self))
|
|
}
|
|
|
|
${SelfName}TestSuite.test("initFromUnsafeMutablePointer") {
|
|
let other = UnsafeMutablePointer<Double>(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<Missile>) ->
|
|
(UnsafeMutablePointer<Missile>, count: Int) -> Void,
|
|
_ withMissiles: Bool = false) {
|
|
let ptr = UnsafeMutablePointer<Missile>(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<Missile>(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<Missile> ->
|
|
(UnsafeMutablePointer<Missile>, 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<Float>(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<Float>(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<Float>(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<Float>(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()
|
|
|