Skip to content

Commit a79a893

Browse files
committed
[test] Add new tests for pointers with explicit nullability.
1 parent bc83940 commit a79a893

File tree

8 files changed

+384
-75
lines changed

8 files changed

+384
-75
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// RUN: rm -rf %t && mkdir -p %t && %S/../../utils/gyb %s -o %t/UnsafeBufferPointer.swift
2+
// RUN: %S/../../utils/line-directive %t/UnsafeBufferPointer.swift -- %target-build-swift %t/UnsafeBufferPointer.swift -o %t/a.out
3+
// RUN: %S/../../utils/line-directive %t/UnsafeBufferPointer.swift -- %target-run %t/a.out
4+
// REQUIRES: executable_test
5+
6+
import StdlibUnittest
7+
8+
// Also import modules which are used by StdlibUnittest internally. This
9+
// workaround is needed to link all required libraries in case we compile
10+
// StdlibUnittest with -sil-serialize-all.
11+
import SwiftPrivate
12+
#if _runtime(_ObjC)
13+
import ObjectiveC
14+
#endif
15+
16+
var UnsafeBufferPointerTestSuite = TestSuite("UnsafeBufferPointer")
17+
var UnsafeMutableBufferPointerTestSuite = TestSuite("UnsafeMutableBufferPointer")
18+
19+
% for (SelfName, SelfType, PointerType) in [
20+
% ('UnsafeBufferPointer', 'UnsafeBufferPointer<Float>', 'UnsafePointer<Float>'),
21+
% ('UnsafeMutableBufferPointer', 'UnsafeMutableBufferPointer<Float>', 'UnsafeMutablePointer<Float>')]:
22+
23+
${SelfName}TestSuite.test("nilBaseAddress") {
24+
let emptyBuffer = ${SelfType}(start: nil, count: 0)
25+
expectEmpty(emptyBuffer.baseAddress)
26+
expectEqual(0, emptyBuffer.count)
27+
expectTrue(emptyBuffer.startIndex == emptyBuffer.endIndex)
28+
29+
var iter = emptyBuffer.makeIterator()
30+
expectEmpty(iter.next())
31+
32+
expectEqual([], Array(emptyBuffer))
33+
}
34+
35+
${SelfName}TestSuite.test("nonNilButEmpty") {
36+
let emptyAllocated = UnsafeMutablePointer<Float>(allocatingCapacity: 0)
37+
defer { emptyAllocated.deallocateCapacity(0) }
38+
39+
let emptyBuffer = ${SelfType}(start: ${PointerType}(emptyAllocated), count: 0)
40+
expectEqual(emptyAllocated, emptyBuffer.baseAddress)
41+
expectEqual(0, emptyBuffer.count)
42+
expectTrue(emptyBuffer.startIndex == emptyBuffer.endIndex)
43+
44+
var iter = emptyBuffer.makeIterator()
45+
expectEmpty(iter.next())
46+
47+
expectEqual([], Array(emptyBuffer))
48+
}
49+
50+
${SelfName}TestSuite.test("nonNilNonEmpty") {
51+
let count = 4
52+
let allocated = UnsafeMutablePointer<Float>(allocatingCapacity: count)
53+
defer { allocated.deallocateCapacity(count) }
54+
allocated.initialize(with: 1.0, count: count)
55+
allocated[count - 1] = 2.0
56+
57+
let buffer = ${SelfType}(start: ${PointerType}(allocated), count: count - 1)
58+
expectEqual(allocated, buffer.baseAddress)
59+
expectEqual(count - 1, buffer.count)
60+
expectEqual(count - 1, buffer.endIndex - buffer.startIndex)
61+
62+
allocated[1] = 0.0
63+
expectEqual(1.0, buffer[0])
64+
expectEqual(0.0, buffer[1])
65+
expectEqual(1.0, buffer[2])
66+
67+
var iter = buffer.makeIterator()
68+
expectEqual(1.0, iter.next())
69+
expectEqual(0.0, iter.next())
70+
expectEqual(1.0, iter.next())
71+
expectEmpty(iter.next())
72+
73+
expectEqual([1.0, 0.0, 1.0], Array(buffer))
74+
75+
expectEqual(2.0, allocated[count-1])
76+
}
77+
78+
${SelfName}TestSuite.test("badCount")
79+
.skip(.custom(
80+
{ _isFastAssertConfiguration() },
81+
reason: "this trap is not guaranteed to happen in -Ounchecked"))
82+
.code {
83+
expectCrashLater()
84+
85+
let emptyAllocated = UnsafeMutablePointer<Float>(allocatingCapacity: 0)
86+
defer { emptyAllocated.deallocateCapacity(0) }
87+
88+
let buffer = ${SelfType}(start: ${PointerType}(emptyAllocated), count: -1)
89+
_ = buffer
90+
}
91+
92+
${SelfName}TestSuite.test("badNilCount")
93+
.skip(.custom(
94+
{ _isFastAssertConfiguration() },
95+
reason: "this trap is not guaranteed to happen in -Ounchecked"))
96+
.code {
97+
expectCrashLater()
98+
99+
let buffer = ${SelfType}(start: nil, count: 1)
100+
_ = buffer
101+
}
102+
103+
% end
104+
105+
UnsafeMutableBufferPointerTestSuite.test("changeElementViaBuffer") {
106+
let count = 4
107+
let allocated = UnsafeMutablePointer<Float>(allocatingCapacity: count)
108+
defer { allocated.deallocateCapacity(count) }
109+
allocated.initialize(with: 1.0, count: count)
110+
allocated[count-1] = -1.0
111+
112+
var buffer = UnsafeMutableBufferPointer(start: allocated, count: count - 1)
113+
114+
buffer[1] = 0.0
115+
expectEqual(1.0, buffer[0])
116+
expectEqual(0.0, buffer[1])
117+
expectEqual(1.0, buffer[2])
118+
119+
expectEqual(1.0, allocated[0])
120+
expectEqual(0.0, allocated[1])
121+
expectEqual(1.0, allocated[2])
122+
expectEqual(-1.0, allocated[count-1])
123+
124+
buffer.sort()
125+
expectEqual(0.0, buffer[0])
126+
expectEqual(1.0, buffer[1])
127+
expectEqual(1.0, buffer[2])
128+
129+
expectEqual(0.0, allocated[0])
130+
expectEqual(1.0, allocated[1])
131+
expectEqual(1.0, allocated[2])
132+
expectEqual(-1.0, allocated[count-1])
133+
}
134+
135+
runAllTests()

test/1_stdlib/UnsafePointer.swift.gyb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,29 +66,73 @@ ${SelfName}TestSuite.test("initFromOpaquePointer") {
6666
let other = OpaquePointer(bitPattern: 0x12345678)!
6767
let ptr = UnsafePointer<Float>(other)
6868
expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self))
69+
70+
let optionalOther: Optional = other
71+
let optionalPointer = UnsafePointer<Float>(optionalOther)
72+
expectNotEmpty(optionalPointer)
73+
expectEqual(0x12345678, unsafeBitCast(optionalPointer, to: Int.self))
74+
75+
let nilOther: Optional<OpaquePointer> = nil
76+
let nilPointer = UnsafePointer<Float>(nilOther)
77+
expectEmpty(nilPointer)
6978
}
7079

7180
${SelfName}TestSuite.test("initFromUnsafePointer") {
7281
let other = UnsafePointer<Double>(bitPattern: 0x12345678)!
7382
let ptr = ${SelfType}(other)
7483
expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self))
84+
85+
let optionalOther: Optional = other
86+
let optionalPointer = ${SelfType}(optionalOther)
87+
expectNotEmpty(optionalPointer)
88+
expectEqual(0x12345678, unsafeBitCast(optionalPointer, to: Int.self))
89+
90+
let nilOther: Optional<UnsafePointer<Double>> = nil
91+
let nilPointer = ${SelfType}(nilOther)
92+
expectEmpty(nilPointer)
7593
}
7694

7795
${SelfName}TestSuite.test("initFromUnsafeMutablePointer") {
7896
let other = UnsafeMutablePointer<Double>(bitPattern: 0x12345678)!
7997
let ptr = ${SelfType}(other)
8098
expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self))
99+
100+
let optionalOther: Optional = other
101+
let optionalPointer = ${SelfType}(optionalOther)
102+
expectNotEmpty(optionalPointer)
103+
expectEqual(0x12345678, unsafeBitCast(optionalPointer, to: Int.self))
104+
105+
let nilOther: Optional<UnsafeMutablePointer<Double>> = nil
106+
let nilPointer = ${SelfType}(nilOther)
107+
expectEmpty(nilPointer)
81108
}
82109

83110
${SelfName}TestSuite.test("initFromInteger") {
84111
do {
85112
let word: Int = 0x12345678
86113
let ptr = ${SelfType}(bitPattern: word)
114+
expectNotEmpty(ptr)
87115
expectEqual(word, unsafeBitCast(ptr, to: Int.self))
88116
}
89117
do {
90118
let uword: UInt = 0x12345678
91119
let ptr = ${SelfType}(bitPattern: uword)
120+
expectNotEmpty(ptr)
121+
expectEqual(uword, unsafeBitCast(ptr, to: UInt.self))
122+
}
123+
}
124+
125+
${SelfName}TestSuite.test("initFromNilBitPattern") {
126+
do {
127+
let word = unsafeBitCast(nil as ${SelfType}?, to: Int.self)
128+
let ptr = ${SelfType}(bitPattern: word)
129+
expectEmpty(ptr)
130+
expectEqual(word, unsafeBitCast(ptr, to: Int.self))
131+
}
132+
do {
133+
let uword = unsafeBitCast(nil as ${SelfType}?, to: UInt.self)
134+
let ptr = ${SelfType}(bitPattern: uword)
135+
expectEmpty(ptr)
92136
expectEqual(uword, unsafeBitCast(ptr, to: UInt.self))
93137
}
94138
}

test/ClangModules/cfuncs_parse.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,32 @@ func test_pointer() {
107107
opaque_pointer_param(op)
108108
}
109109

110+
func test_pointer_nonnull() {
111+
var i: CInt = 0
112+
var ia: [CInt] = [1, 2, 3]
113+
var f: CFloat = 0
114+
var fa: [CFloat] = [1, 2, 3]
115+
116+
nonnull_param_pointer(&i)
117+
nonnull_param_pointer(&ia)
118+
119+
nonnull_param_const_pointer(&i)
120+
nonnull_param_const_pointer(ia)
121+
nonnull_param_const_pointer([1, 2, 3])
122+
123+
nonnull_param_void_pointer(&i)
124+
nonnull_param_void_pointer(&ia)
125+
nonnull_param_void_pointer(&f)
126+
nonnull_param_void_pointer(&fa)
127+
128+
nonnull_param_const_void_pointer(&i)
129+
nonnull_param_const_void_pointer(ia)
130+
// FIXME: nonnull_param_const_void_pointer([1, 2, 3])
131+
nonnull_param_const_void_pointer(&f)
132+
nonnull_param_const_void_pointer(fa)
133+
// FIXME: nonnull_param_const_void_pointer([1.0, 2.0, 3.0])
134+
}
135+
110136
func test_decay() {
111137
decay_param_array(nil as UnsafeMutablePointer<CInt>?)
112138
var i: CInt = 0

test/Inputs/clang-importer-sdk/usr/include/cfuncs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ void param_const_pointer(const int *p);
3030
void param_void_pointer(void *p);
3131
void param_const_void_pointer(const void *p);
3232

33+
void nonnull_param_pointer(int * _Nonnull p);
34+
void nonnull_param_const_pointer(const int * _Nonnull p);
35+
36+
void nonnull_param_void_pointer(void * _Nonnull p);
37+
void nonnull_param_const_void_pointer(const void * _Nonnull p);
38+
3339
void decay_param_array(int p[]);
3440
void decay_param_const_array(const int p[]);
3541

test/Interpreter/process_arguments.swift

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,36 @@
55

66
// REQUIRES: swift_interpreter
77

8-
print("Begin")
8+
print("Begin arguments")
99
for arg in Process.arguments { print(arg) }
10-
print("End")
10+
print("End arguments")
1111

12-
// CHECK-NONE: Begin
12+
// CHECK-NONE: Begin arguments
1313
// CHECK-NONE-NEXT: {{.*}}process_arguments.swift
14-
// CHECK-NONE-NEXT: End
14+
// CHECK-NONE-NEXT: End arguments
1515

16-
// CHECK-THREE: Begin
16+
// CHECK-THREE: Begin arguments
1717
// CHECK-THREE-NEXT: {{.*}}process_arguments.swift
1818
// CHECK-THREE-NEXT: a
1919
// CHECK-THREE-NEXT: b
2020
// CHECK-THREE-NEXT: c
21-
// CHECK-THREE-NEXT: End
21+
// CHECK-THREE-NEXT: End arguments
22+
23+
print("Begin unsafeArgv")
24+
for i in 0...Int(Process.argc) {
25+
print(Process.unsafeArgv[i].map { String(cString: $0) } ?? "(null)")
26+
}
27+
print("End unsafeArgv")
28+
29+
// CHECK-NONE: Begin unsafeArgv
30+
// CHECK-NONE-NEXT: {{.*}}process_arguments.swift
31+
// CHECK-NONE-NEXT: (null)
32+
// CHECK-NONE-NEXT: End unsafeArgv
33+
34+
// CHECK-THREE: Begin unsafeArgv
35+
// CHECK-THREE-NEXT: {{.*}}process_arguments.swift
36+
// CHECK-THREE-NEXT: a
37+
// CHECK-THREE-NEXT: b
38+
// CHECK-THREE-NEXT: c
39+
// CHECK-THREE-NEXT: (null)
40+
// CHECK-THREE-NEXT: End unsafeArgv

0 commit comments

Comments
 (0)