mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
WASI doesn't support spawning a subprocess, so crash tests crashes the test harness itself. Those should be skipped until proper subprocess support is available.
567 lines
17 KiB
Swift
567 lines
17 KiB
Swift
// 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<Float>'),
|
|
% ('UnsafeMutablePointer', 'UnsafeMutablePointer<Float>'),
|
|
% ('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<OpaquePointer> = 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<UnsafeRawPointer> = nil
|
|
let nilPointer = UnsafeMutableRawPointer(mutating: nilOther)
|
|
expectNil(nilPointer)
|
|
}
|
|
% end
|
|
|
|
% for (SelfName, SelfType) in [
|
|
% ('UnsafePointer', 'UnsafePointer<Float>'),
|
|
% ('UnsafeMutablePointer', 'UnsafeMutablePointer<Float>'),
|
|
% ('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<Float>'),
|
|
% ('UnsafeRawPointer', 'UnsafeRawPointer'),
|
|
% ('UnsafeMutableRawPointer', 'UnsafeMutableRawPointer')]:
|
|
|
|
${SelfName}TestSuite.test("initFromUnsafeMutablePointer") {
|
|
let other = UnsafeMutablePointer<Float>(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<UnsafeMutablePointer<Float>> = nil
|
|
let nilPointer = ${SelfType}(nilOther)
|
|
expectNil(nilPointer)
|
|
}
|
|
|
|
% end
|
|
|
|
% for (SelfName, SelfType) in [
|
|
% ('UnsafePointer', 'UnsafePointer<Float>'),
|
|
% ('UnsafeRawPointer', 'UnsafeRawPointer')]:
|
|
|
|
${SelfName}TestSuite.test("initFromUnsafePointer") {
|
|
let other = UnsafePointer<Float>(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<UnsafePointer<Float>> = 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<UnsafeMutableRawPointer> = 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<Missile>) ->
|
|
(UnsafeMutablePointer<Missile>, _ count: Int) -> Void) {
|
|
let ptr = UnsafeMutablePointer<Missile>.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<Missile>.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<Missile>) -> (UnsafeMutablePointer<Missile>, _ count: Int) -> Void),
|
|
_ m: Bool
|
|
) -> (Check) -> Void {
|
|
return { checkPointerCorrectness($0, m, f) }
|
|
}
|
|
|
|
func checkPtr(
|
|
_ f: @escaping ((UnsafeMutablePointer<Missile>) -> (UnsafePointer<Missile>, _ 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<Missile>.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<Missile>.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<Float>'),
|
|
% ('UnsafeMutablePointer', 'UnsafeMutablePointer<Float>'),
|
|
% ('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<Int>.allocate(capacity: 4)
|
|
defer { mutablePtrI.deallocate() }
|
|
let ptrI = ${SelfName}<Int>(mutablePtrI)
|
|
ptrI.withMemoryRebound(to: UInt.self, capacity: 4) {
|
|
// Make sure the closure argument isa $SelfName
|
|
let ptrU: ${SelfName}<UInt> = $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<Int>.allocate(capacity: 4)
|
|
defer { mutablePtrI.deallocate() }
|
|
let ptrI = ${SelfName}<Int>(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}<UInt> = $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<Example>.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<Example>.offset(of: \.b)!
|
|
let p = UnsafePointer<Example>(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()
|