summaryrefslogtreecommitdiffstats
path: root/tests/ui/packed/packed-struct-size.rs
blob: c832c7cfad5cd9925389c8fb3b03b8aa6a442919 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// run-pass
#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]

use std::mem;

#[repr(packed)]
struct P1S4 {
    a: u8,
    b: [u8;  3],
}

#[repr(packed(2))]
struct P2S4 {
    a: u8,
    b: [u8;  3],
}

#[repr(packed)]
struct P1S5 {
    a: u8,
    b: u32
}

#[repr(packed(2))]
struct P2S2 {
    a: u8,
    b: u8
}

#[repr(packed(2))]
struct P2S6 {
    a: u8,
    b: u32
}

#[repr(packed(2))]
struct P2S12 {
    a: u32,
    b: u64
}

#[repr(packed)]
struct P1S13 {
    a: i64,
    b: f32,
    c: u8,
}

#[repr(packed(2))]
struct P2S14 {
    a: i64,
    b: f32,
    c: u8,
}

#[repr(packed(4))]
struct P4S16 {
    a: u8,
    b: f32,
    c: i64,
    d: u16,
}

#[repr(C, packed(4))]
struct P4CS20 {
    a: u8,
    b: f32,
    c: i64,
    d: u16,
}

enum Foo {
    Bar = 1,
    Baz = 2
}

#[repr(packed)]
struct P1S3_Foo {
    a: u8,
    b: u16,
    c: Foo
}

#[repr(packed(2))]
struct P2_Foo {
    a: Foo,
}

#[repr(packed(2))]
struct P2S3_Foo {
    a: u8,
    b: u16,
    c: Foo
}

#[repr(packed)]
struct P1S7_Option {
    a: f32,
    b: u8,
    c: u16,
    d: Option<Box<f64>>
}

#[repr(packed(2))]
struct P2_Option {
    a: Option<Box<f64>>
}

#[repr(packed(2))]
struct P2S7_Option {
    a: f32,
    b: u8,
    c: u16,
    d: Option<Box<f64>>
}

// Placing packed structs in statics should work
static TEST_P1S4: P1S4 = P1S4 { a: 1, b: [2, 3, 4] };
static TEST_P1S5: P1S5 = P1S5 { a: 3, b: 67 };
static TEST_P1S3_Foo: P1S3_Foo = P1S3_Foo { a: 1, b: 2, c: Foo::Baz };
static TEST_P2S2: P2S2 = P2S2 { a: 1, b: 2 };
static TEST_P2S4: P2S4 = P2S4 { a: 1, b: [2, 3, 4] };
static TEST_P2S6: P2S6 = P2S6 { a: 1, b: 2 };
static TEST_P2S12: P2S12 = P2S12 { a: 1, b: 2 };
static TEST_P4S16: P4S16 = P4S16 { a: 1, b: 2.0, c: 3, d: 4 };
static TEST_P4CS20: P4CS20 = P4CS20 { a: 1, b: 2.0, c: 3, d: 4 };

fn align_to(value: usize, align: usize) -> usize {
    (value + (align - 1)) & !(align - 1)
}

macro_rules! check {
    ($t:ty, $align:expr, $size:expr) => ({
        assert_eq!(mem::align_of::<$t>(), $align);
        assert_eq!(mem::size_of::<$t>(), $size);
    });
}

pub fn main() {
    check!(P1S4, 1, 4);
    check!(P1S5, 1, 5);
    check!(P1S13, 1, 13);
    check!(P1S3_Foo, 1, 3 + mem::size_of::<Foo>());
    check!(P1S7_Option, 1, 7 + mem::size_of::<Option<Box<f64>>>());

    check!(P2S2, 1, 2);
    check!(P2S4, 1, 4);
    check!(P2S6, 2, 6);
    check!(P2S12, 2, 12);
    check!(P2S14, 2, 14);
    check!(P4S16, 4, 16);
    check!(P4CS20, 4, 20);
    check!(P2S3_Foo, 2, align_to(3 + mem::size_of::<P2_Foo>(), 2));
    check!(P2S7_Option, 2, align_to(7 + mem::size_of::<P2_Option>(), 2));
}