Skip to content

Commit 7850660

Browse files
authored
Add union tests (#31)
1 parent 34f0cdd commit 7850660

16 files changed

Lines changed: 614 additions & 0 deletions
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
extern crate libcc2rs;
2+
use libcc2rs::*;
3+
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::io::prelude::*;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::AsFd;
8+
use std::rc::{Rc, Weak};
9+
#[derive(Default)]
10+
pub struct basic {
11+
pub i: Value<i32>,
12+
pub f: Value<f32>,
13+
}
14+
impl ByteRepr for basic {}
15+
pub fn main() {
16+
std::process::exit(main_0());
17+
}
18+
fn main_0() -> i32 {
19+
let u: Value<basic> = <Value<basic>>::default();
20+
(*(*u.borrow()).i.borrow_mut()) = 42;
21+
assert!(((*(*u.borrow()).i.borrow()) == 42));
22+
(*(*u.borrow()).f.borrow_mut()) = 3.140000105E+0;
23+
assert!(((*(*u.borrow()).f.borrow()) == 3.140000105E+0));
24+
return 0;
25+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
#[derive(Copy, Clone, Default)]
10+
pub struct basic {
11+
pub i: i32,
12+
pub f: f32,
13+
}
14+
pub fn main() {
15+
unsafe {
16+
std::process::exit(main_0() as i32);
17+
}
18+
}
19+
unsafe fn main_0() -> i32 {
20+
let mut u: basic = <basic>::default();
21+
u.i = 42;
22+
assert!(((u.i) == (42)));
23+
u.f = 3.140000105E+0;
24+
assert!(((u.f) == (3.140000105E+0)));
25+
return 0;
26+
}

tests/unit/union_addrof_external.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// translation-fail
2+
#include <assert.h>
3+
#include <stddef.h>
4+
#include <stdint.h>
5+
#include <string.h>
6+
7+
struct record {
8+
uint16_t code;
9+
uint16_t lo;
10+
uint32_t hi;
11+
char pad[8];
12+
};
13+
14+
struct Container {
15+
union {
16+
struct record h;
17+
char raw[128];
18+
} view;
19+
};
20+
21+
static void fill(void *out, size_t cap) {
22+
unsigned char src[16] = {0};
23+
src[0] = 2;
24+
src[1] = 0;
25+
src[2] = 0x00;
26+
src[3] = 0x50;
27+
src[4] = 0x7F;
28+
src[5] = 0x00;
29+
src[6] = 0x00;
30+
src[7] = 0x01;
31+
size_t n = sizeof(src) < cap ? sizeof(src) : cap;
32+
memcpy(out, src, n);
33+
}
34+
35+
int main(void) {
36+
struct Container c;
37+
memset(&c, 0, sizeof(c));
38+
39+
fill((void *)&c.view, sizeof(c.view));
40+
41+
assert(c.view.h.code == 2);
42+
assert(((unsigned char *)&c.view.h.lo)[0] == 0x00);
43+
assert(((unsigned char *)&c.view.h.lo)[1] == 0x50);
44+
45+
assert(c.view.raw[0] == 2);
46+
assert((unsigned char)c.view.raw[3] == 0x50);
47+
48+
return 0;
49+
}

tests/unit/union_basic.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <assert.h>
2+
3+
union basic {
4+
int i;
5+
float f;
6+
};
7+
8+
int main(void) {
9+
union basic u;
10+
11+
u.i = 42;
12+
assert(u.i == 42);
13+
14+
u.f = 3.14f;
15+
assert(u.f == 3.14f);
16+
17+
return 0;
18+
}

tests/unit/union_cross_arm_cast.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// translation-fail
2+
#include <assert.h>
3+
#include <stddef.h>
4+
#include <stdint.h>
5+
#include <string.h>
6+
7+
struct shape_a {
8+
uint16_t code;
9+
char pad[14];
10+
};
11+
12+
struct shape_b {
13+
uint16_t code;
14+
uint16_t lo;
15+
uint32_t mid;
16+
uint8_t fill[16];
17+
uint32_t tail;
18+
};
19+
20+
struct Container {
21+
unsigned int len;
22+
union {
23+
struct shape_a a;
24+
struct shape_b b;
25+
char raw[64];
26+
} u;
27+
};
28+
29+
int main(void) {
30+
struct Container c;
31+
memset(&c, 0, sizeof(c));
32+
33+
c.u.a.code = 10;
34+
c.len = sizeof(struct shape_b);
35+
36+
((struct shape_b *)(void *)&c.u.a)->tail = 0xDEADBEEF;
37+
38+
assert(c.u.b.tail == 0xDEADBEEF);
39+
assert(c.u.b.code == 10);
40+
41+
c.u.b.lo = 0x1F90;
42+
assert(((unsigned char *)&c.u.raw)[2] == 0x90);
43+
assert(((unsigned char *)&c.u.raw)[3] == 0x1F);
44+
45+
return 0;
46+
}

tests/unit/union_field_alignment.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// translation-fail
2+
#include <assert.h>
3+
#include <stddef.h>
4+
#include <stdint.h>
5+
6+
// Just check if this compiles. node::x::aligner is used to impose a specific
7+
// alignment on the bytes field.
8+
struct node {
9+
struct node *next;
10+
union {
11+
uint8_t bytes[1];
12+
void *aligner;
13+
} x;
14+
};
15+
16+
int main(void) {
17+
struct node n;
18+
n.next = 0;
19+
n.x.bytes[0] = 0xAB;
20+
assert(n.x.bytes[0] == 0xAB);
21+
return 0;
22+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// translation-fail
2+
#include <assert.h>
3+
#include <stddef.h>
4+
#include <stdint.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
8+
struct node {
9+
size_t len;
10+
union {
11+
uint8_t bytes[1];
12+
void *aligner;
13+
} x;
14+
};
15+
16+
int main(void) {
17+
size_t tail_size = 32;
18+
struct node *n = (struct node *)malloc(sizeof(struct node) + tail_size);
19+
n->len = tail_size;
20+
21+
for (size_t i = 0; i < tail_size; i++) {
22+
n->x.bytes[i] = (uint8_t)(i & 0xFF);
23+
}
24+
for (size_t i = 0; i < tail_size; i++) {
25+
assert(n->x.bytes[i] == (uint8_t)(i & 0xFF));
26+
}
27+
28+
uint8_t *p = &n->x.bytes[10];
29+
assert(*p == 10);
30+
*p = 0xAA;
31+
assert(n->x.bytes[10] == 0xAA);
32+
33+
free(n);
34+
return 0;
35+
}

tests/unit/union_memset_memcpy.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// translation-fail
2+
#include <assert.h>
3+
#include <stddef.h>
4+
#include <stdint.h>
5+
#include <string.h>
6+
7+
struct shape_a {
8+
uint16_t code;
9+
char pad[14];
10+
};
11+
12+
struct shape_b {
13+
uint16_t code;
14+
uint16_t lo;
15+
uint32_t hi;
16+
char fill[8];
17+
};
18+
19+
struct Container {
20+
union {
21+
struct shape_a a;
22+
struct shape_b b;
23+
char raw[256];
24+
} view;
25+
};
26+
27+
int main(void) {
28+
struct Container c;
29+
30+
memset(&c, 0, sizeof(c));
31+
assert(c.view.a.code == 0);
32+
assert(c.view.b.lo == 0);
33+
assert(c.view.raw[0] == 0);
34+
assert(c.view.raw[255] == 0);
35+
36+
unsigned char src[16] = {0};
37+
src[0] = 2;
38+
src[2] = 0x50;
39+
src[3] = 0x00;
40+
src[4] = 0x7F;
41+
src[5] = 0x00;
42+
src[6] = 0x00;
43+
src[7] = 0x01;
44+
size_t len = 16;
45+
assert(len <= sizeof(c.view.raw));
46+
memcpy(&c.view.raw, src, len);
47+
48+
assert(c.view.b.code == 2);
49+
assert(((unsigned char *)&c.view.b.lo)[0] == 0x50);
50+
51+
memset(&c, 0, sizeof(c));
52+
assert(c.view.b.code == 0);
53+
54+
return 0;
55+
}

tests/unit/union_nested.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// translation-fail
2+
#include <assert.h>
3+
#include <stdint.h>
4+
#include <string.h>
5+
6+
struct record {
7+
uint16_t code;
8+
char pad[14];
9+
};
10+
11+
struct inner {
12+
union {
13+
struct record h;
14+
char raw[128];
15+
} view;
16+
};
17+
18+
struct Outer {
19+
int kind;
20+
int level;
21+
int variant;
22+
unsigned int len;
23+
union {
24+
struct record h;
25+
struct inner nested;
26+
} body;
27+
};
28+
29+
int main(void) {
30+
struct Outer ex;
31+
memset(&ex, 0, sizeof(ex));
32+
33+
ex.kind = 2;
34+
ex.level = 1;
35+
ex.variant = 6;
36+
ex.len = sizeof(struct record);
37+
ex.body.h.code = 2;
38+
ex.body.h.pad[0] = 'X';
39+
40+
assert(ex.body.h.code == 2);
41+
assert(ex.body.h.pad[0] == 'X');
42+
43+
assert(ex.body.nested.view.h.code == 2);
44+
return 0;
45+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// translation-fail
2+
#include <assert.h>
3+
4+
struct node_a {
5+
int n;
6+
};
7+
8+
struct node_b {
9+
void *data;
10+
struct node_b *next;
11+
};
12+
13+
int main(void) {
14+
struct node_a a = {123};
15+
16+
union {
17+
struct node_a *to_a;
18+
struct node_b *to_b;
19+
} ptr;
20+
21+
ptr.to_a = &a;
22+
struct node_b *out = ptr.to_b;
23+
24+
assert((void *)out == (void *)&a);
25+
return 0;
26+
}

0 commit comments

Comments
 (0)