]> git.proxmox.com Git - rustc.git/blame - src/libcore/tests/ptr.rs
New upstream version 1.33.0+dfsg1
[rustc.git] / src / libcore / tests / ptr.rs
CommitLineData
1a4d82fc 1use core::ptr::*;
476ff2be 2use core::cell::RefCell;
1a4d82fc
JJ
3
4#[test]
5fn test() {
6 unsafe {
7 struct Pair {
c34b1796
AL
8 fst: isize,
9 snd: isize
1a4d82fc
JJ
10 };
11 let mut p = Pair {fst: 10, snd: 20};
12 let pptr: *mut Pair = &mut p;
e9174d1e 13 let iptr: *mut isize = pptr as *mut isize;
1a4d82fc
JJ
14 assert_eq!(*iptr, 10);
15 *iptr = 30;
16 assert_eq!(*iptr, 30);
17 assert_eq!(p.fst, 30);
18
19 *pptr = Pair {fst: 50, snd: 60};
20 assert_eq!(*iptr, 50);
21 assert_eq!(p.fst, 50);
22 assert_eq!(p.snd, 60);
23
24 let v0 = vec![32000u16, 32001u16, 32002u16];
25 let mut v1 = vec![0u16, 0u16, 0u16];
26
c34b1796 27 copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
1a4d82fc
JJ
28 assert!((v1[0] == 0u16 &&
29 v1[1] == 32001u16 &&
30 v1[2] == 0u16));
c34b1796 31 copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
1a4d82fc
JJ
32 assert!((v1[0] == 32002u16 &&
33 v1[1] == 32001u16 &&
34 v1[2] == 0u16));
c34b1796 35 copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
1a4d82fc
JJ
36 assert!((v1[0] == 32002u16 &&
37 v1[1] == 32001u16 &&
38 v1[2] == 32000u16));
39 }
40}
41
42#[test]
43fn test_is_null() {
c34b1796 44 let p: *const isize = null();
1a4d82fc
JJ
45 assert!(p.is_null());
46
47 let q = unsafe { p.offset(1) };
48 assert!(!q.is_null());
49
c34b1796 50 let mp: *mut isize = null_mut();
1a4d82fc
JJ
51 assert!(mp.is_null());
52
53 let mq = unsafe { mp.offset(1) };
54 assert!(!mq.is_null());
ff7c6d11
XL
55
56 // Pointers to unsized types -- slices
57 let s: &mut [u8] = &mut [1, 2, 3];
58 let cs: *const [u8] = s;
59 assert!(!cs.is_null());
60
61 let ms: *mut [u8] = s;
62 assert!(!ms.is_null());
63
64 let cz: *const [u8] = &[];
65 assert!(!cz.is_null());
66
67 let mz: *mut [u8] = &mut [];
68 assert!(!mz.is_null());
69
70 let ncs: *const [u8] = null::<[u8; 3]>();
71 assert!(ncs.is_null());
72
73 let nms: *mut [u8] = null_mut::<[u8; 3]>();
74 assert!(nms.is_null());
75
76 // Pointers to unsized types -- trait objects
8faf50e0 77 let ci: *const dyn ToString = &3;
ff7c6d11
XL
78 assert!(!ci.is_null());
79
8faf50e0 80 let mi: *mut dyn ToString = &mut 3;
ff7c6d11
XL
81 assert!(!mi.is_null());
82
8faf50e0 83 let nci: *const dyn ToString = null::<isize>();
ff7c6d11
XL
84 assert!(nci.is_null());
85
8faf50e0 86 let nmi: *mut dyn ToString = null_mut::<isize>();
ff7c6d11 87 assert!(nmi.is_null());
1a4d82fc
JJ
88}
89
90#[test]
91fn test_as_ref() {
92 unsafe {
c34b1796 93 let p: *const isize = null();
1a4d82fc
JJ
94 assert_eq!(p.as_ref(), None);
95
c34b1796 96 let q: *const isize = &2;
1a4d82fc
JJ
97 assert_eq!(q.as_ref().unwrap(), &2);
98
c34b1796 99 let p: *mut isize = null_mut();
1a4d82fc
JJ
100 assert_eq!(p.as_ref(), None);
101
c34b1796 102 let q: *mut isize = &mut 2;
1a4d82fc
JJ
103 assert_eq!(q.as_ref().unwrap(), &2);
104
105 // Lifetime inference
c34b1796 106 let u = 2isize;
1a4d82fc 107 {
c34b1796 108 let p = &u as *const isize;
1a4d82fc
JJ
109 assert_eq!(p.as_ref().unwrap(), &2);
110 }
abe05a73
XL
111
112 // Pointers to unsized types -- slices
113 let s: &mut [u8] = &mut [1, 2, 3];
114 let cs: *const [u8] = s;
115 assert_eq!(cs.as_ref(), Some(&*s));
116
117 let ms: *mut [u8] = s;
118 assert_eq!(ms.as_ref(), Some(&*s));
119
120 let cz: *const [u8] = &[];
121 assert_eq!(cz.as_ref(), Some(&[][..]));
122
123 let mz: *mut [u8] = &mut [];
124 assert_eq!(mz.as_ref(), Some(&[][..]));
125
126 let ncs: *const [u8] = null::<[u8; 3]>();
127 assert_eq!(ncs.as_ref(), None);
128
129 let nms: *mut [u8] = null_mut::<[u8; 3]>();
130 assert_eq!(nms.as_ref(), None);
131
132 // Pointers to unsized types -- trait objects
8faf50e0 133 let ci: *const dyn ToString = &3;
abe05a73
XL
134 assert!(ci.as_ref().is_some());
135
8faf50e0 136 let mi: *mut dyn ToString = &mut 3;
abe05a73
XL
137 assert!(mi.as_ref().is_some());
138
8faf50e0 139 let nci: *const dyn ToString = null::<isize>();
abe05a73
XL
140 assert!(nci.as_ref().is_none());
141
8faf50e0 142 let nmi: *mut dyn ToString = null_mut::<isize>();
abe05a73 143 assert!(nmi.as_ref().is_none());
1a4d82fc
JJ
144 }
145}
146
147#[test]
148fn test_as_mut() {
149 unsafe {
c34b1796 150 let p: *mut isize = null_mut();
1a4d82fc
JJ
151 assert!(p.as_mut() == None);
152
c34b1796 153 let q: *mut isize = &mut 2;
1a4d82fc
JJ
154 assert!(q.as_mut().unwrap() == &mut 2);
155
156 // Lifetime inference
c34b1796 157 let mut u = 2isize;
1a4d82fc 158 {
c34b1796 159 let p = &mut u as *mut isize;
1a4d82fc
JJ
160 assert!(p.as_mut().unwrap() == &mut 2);
161 }
abe05a73
XL
162
163 // Pointers to unsized types -- slices
164 let s: &mut [u8] = &mut [1, 2, 3];
165 let ms: *mut [u8] = s;
166 assert_eq!(ms.as_mut(), Some(s));
167
168 let mz: *mut [u8] = &mut [];
169 assert_eq!(mz.as_mut(), Some(&mut [][..]));
170
171 let nms: *mut [u8] = null_mut::<[u8; 3]>();
172 assert_eq!(nms.as_mut(), None);
173
174 // Pointers to unsized types -- trait objects
8faf50e0 175 let mi: *mut dyn ToString = &mut 3;
abe05a73
XL
176 assert!(mi.as_mut().is_some());
177
8faf50e0 178 let nmi: *mut dyn ToString = null_mut::<isize>();
abe05a73 179 assert!(nmi.as_mut().is_none());
1a4d82fc
JJ
180 }
181}
182
183#[test]
184fn test_ptr_addition() {
185 unsafe {
c1a9b12d 186 let xs = vec![5; 16];
1a4d82fc
JJ
187 let mut ptr = xs.as_ptr();
188 let end = ptr.offset(16);
189
190 while ptr < end {
191 assert_eq!(*ptr, 5);
192 ptr = ptr.offset(1);
193 }
194
195 let mut xs_mut = xs;
196 let mut m_ptr = xs_mut.as_mut_ptr();
197 let m_end = m_ptr.offset(16);
198
199 while m_ptr < m_end {
200 *m_ptr += 5;
201 m_ptr = m_ptr.offset(1);
202 }
203
c1a9b12d 204 assert!(xs_mut == vec![10; 16]);
1a4d82fc
JJ
205 }
206}
207
208#[test]
209fn test_ptr_subtraction() {
210 unsafe {
211 let xs = vec![0,1,2,3,4,5,6,7,8,9];
c34b1796 212 let mut idx = 9;
1a4d82fc
JJ
213 let ptr = xs.as_ptr();
214
c34b1796
AL
215 while idx >= 0 {
216 assert_eq!(*(ptr.offset(idx as isize)), idx as isize);
217 idx = idx - 1;
1a4d82fc
JJ
218 }
219
220 let mut xs_mut = xs;
221 let m_start = xs_mut.as_mut_ptr();
222 let mut m_ptr = m_start.offset(9);
223
224 while m_ptr >= m_start {
225 *m_ptr += *m_ptr;
226 m_ptr = m_ptr.offset(-1);
227 }
228
c34b1796 229 assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
1a4d82fc
JJ
230 }
231}
232
233#[test]
234fn test_set_memory() {
235 let mut xs = [0u8; 20];
236 let ptr = xs.as_mut_ptr();
c34b1796 237 unsafe { write_bytes(ptr, 5u8, xs.len()); }
1a4d82fc
JJ
238 assert!(xs == [5u8; 20]);
239}
85aaf69f
SL
240
241#[test]
2c00a5a8 242fn test_unsized_nonnull() {
7cac9316 243 let xs: &[i32] = &[1, 2, 3];
2c00a5a8 244 let ptr = unsafe { NonNull::new_unchecked(xs as *const [i32] as *mut [i32]) };
7cac9316
XL
245 let ys = unsafe { ptr.as_ref() };
246 let zs: &[i32] = &[1, 2, 3];
85aaf69f
SL
247 assert!(ys == zs);
248}
5bcae85e
SL
249
250#[test]
9e0c209e
SL
251#[allow(warnings)]
252// Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the
253// ABI, or even point to an actual executable code, because the function itself is never invoked.
254#[no_mangle]
255pub fn test_variadic_fnptr() {
5bcae85e 256 use core::hash::{Hash, SipHasher};
9e0c209e
SL
257 extern {
258 fn test_variadic_fnptr(_: u64, ...) -> f64;
5bcae85e 259 }
9e0c209e 260 let p: unsafe extern fn(u64, ...) -> f64 = test_variadic_fnptr;
5bcae85e
SL
261 let q = p.clone();
262 assert_eq!(p, q);
263 assert!(!(p < q));
264 let mut s = SipHasher::new();
265 assert_eq!(p.hash(&mut s), q.hash(&mut s));
266}
476ff2be
SL
267
268#[test]
269fn write_unaligned_drop() {
270 thread_local! {
271 static DROPS: RefCell<Vec<u32>> = RefCell::new(Vec::new());
272 }
273
274 struct Dropper(u32);
275
276 impl Drop for Dropper {
277 fn drop(&mut self) {
278 DROPS.with(|d| d.borrow_mut().push(self.0));
279 }
280 }
281
282 {
283 let c = Dropper(0);
284 let mut t = Dropper(1);
285 unsafe { write_unaligned(&mut t, c); }
286 }
287 DROPS.with(|d| assert_eq!(*d.borrow(), [0]));
288}
94b46f34
XL
289
290#[test]
291fn align_offset_zst() {
292 // For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at
293 // all, because no amount of elements will align the pointer.
294 let mut p = 1;
295 while p < 1024 {
296 assert_eq!((p as *const ()).align_offset(p), 0);
297 if p != 1 {
298 assert_eq!(((p + 1) as *const ()).align_offset(p), !0);
299 }
300 p = (p + 1).next_power_of_two();
301 }
302}
303
304#[test]
305fn align_offset_stride1() {
306 // For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
307 // number of bytes.
308 let mut align = 1;
309 while align < 1024 {
310 for ptr in 1..2*align {
311 let expected = ptr % align;
312 let offset = if expected == 0 { 0 } else { align - expected };
313 assert_eq!((ptr as *const u8).align_offset(align), offset,
314 "ptr = {}, align = {}, size = 1", ptr, align);
315 }
316 align = (align + 1).next_power_of_two();
317 }
318}
319
320#[test]
321fn align_offset_weird_strides() {
322 #[repr(packed)]
323 struct A3(u16, u8);
324 struct A4(u32);
325 #[repr(packed)]
326 struct A5(u32, u8);
327 #[repr(packed)]
328 struct A6(u32, u16);
329 #[repr(packed)]
330 struct A7(u32, u16, u8);
331 #[repr(packed)]
332 struct A8(u32, u32);
333 #[repr(packed)]
334 struct A9(u32, u32, u8);
335 #[repr(packed)]
336 struct A10(u32, u32, u16);
337
338 unsafe fn test_weird_stride<T>(ptr: *const T, align: usize) -> bool {
339 let numptr = ptr as usize;
340 let mut expected = usize::max_value();
341 // Naive but definitely correct way to find the *first* aligned element of stride::<T>.
342 for el in 0..align {
343 if (numptr + el * ::std::mem::size_of::<T>()) % align == 0 {
344 expected = el;
345 break;
346 }
347 }
348 let got = ptr.align_offset(align);
349 if got != expected {
350 eprintln!("aligning {:p} (with stride of {}) to {}, expected {}, got {}", ptr,
351 ::std::mem::size_of::<T>(), align, expected, got);
352 return true;
353 }
354 return false;
355 }
356
357 // For pointers of stride != 1, we verify the algorithm against the naivest possible
358 // implementation
359 let mut align = 1;
360 let mut x = false;
361 while align < 1024 {
362 for ptr in 1usize..4*align {
363 unsafe {
364 x |= test_weird_stride::<A3>(ptr as *const A3, align);
365 x |= test_weird_stride::<A4>(ptr as *const A4, align);
366 x |= test_weird_stride::<A5>(ptr as *const A5, align);
367 x |= test_weird_stride::<A6>(ptr as *const A6, align);
368 x |= test_weird_stride::<A7>(ptr as *const A7, align);
369 x |= test_weird_stride::<A8>(ptr as *const A8, align);
370 x |= test_weird_stride::<A9>(ptr as *const A9, align);
371 x |= test_weird_stride::<A10>(ptr as *const A10, align);
372 }
373 }
374 align = (align + 1).next_power_of_two();
375 }
376 assert!(!x);
377}