Skip to content

Commit 0532209

Browse files
adpaco-awstedinski
authored andcommitted
Add a test for bswap (rust-lang#1023)
* Add a test for `bswap` * Address comments
1 parent 9416fda commit 0532209

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

tests/kani/Intrinsics/bswap.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// Check that `bswap` returns the expected results.
5+
// https://doc.rust-lang.org/std/intrinsics/fn.bswap.html
6+
7+
// `bswap` reverses the bytes in an integer type `T`, for example:
8+
//
9+
// ```
10+
// let n = 0x12345678u32;
11+
// let m = std::intrinsics::bswap(n);
12+
13+
// assert_eq!(m, 0x78563412);
14+
// ```
15+
16+
#![feature(core_intrinsics)]
17+
18+
const BITS_PER_BYTE: usize = 8;
19+
20+
macro_rules! test_bswap_intrinsic {
21+
($ty:ty, $check_name:ident, $get_byte_name:ident) => {
22+
// Gets the i-th byte in `x`
23+
fn $get_byte_name(x: $ty, i: usize) -> $ty {
24+
let mask = 0xFF as $ty << i * BITS_PER_BYTE;
25+
let masked_res = x & mask;
26+
let bytes_res = masked_res >> i * BITS_PER_BYTE;
27+
bytes_res
28+
}
29+
30+
// Checks that the order of bytes in the original integer is reversed in
31+
// the swapped integer
32+
fn $check_name(a: $ty, b: $ty) {
33+
let bytes = std::mem::size_of::<$ty>();
34+
let i: usize = kani::any();
35+
kani::assume(i < bytes);
36+
let a_byte = $get_byte_name(a, i);
37+
let b_byte = $get_byte_name(b, bytes - i - 1);
38+
assert!(a_byte == b_byte);
39+
}
40+
41+
let x: $ty = kani::any();
42+
$check_name(x, std::intrinsics::bswap(x));
43+
}
44+
}
45+
46+
#[kani::proof]
47+
fn test_bswap_u8() {
48+
test_bswap_intrinsic!(u8, check_bswap_u8, get_byte_at_u8);
49+
}
50+
51+
#[kani::proof]
52+
fn test_bswap_u16() {
53+
test_bswap_intrinsic!(u16, check_bswap_u16, get_byte_at_u16);
54+
}
55+
56+
#[kani::proof]
57+
fn test_bswap_u32() {
58+
test_bswap_intrinsic!(u32, check_bswap_u32, get_byte_at_u32);
59+
}
60+
61+
#[kani::proof]
62+
fn test_bswap_u64() {
63+
test_bswap_intrinsic!(u64, check_bswap_u64, get_byte_at_u64);
64+
}
65+
66+
#[kani::proof]
67+
fn test_bswap_u128() {
68+
test_bswap_intrinsic!(u128, check_bswap_u128, get_byte_at_u128);
69+
}
70+
71+
// `bswap` also works with signed integer types, but this causes overflows
72+
// unless we restrict their values considerably (due to how bytes are
73+
// extracted), making the signed versions not very interesting to test here.
74+
// https://github.com/model-checking/kani/issues/934

0 commit comments

Comments
 (0)