Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions tests/unit/out/refcount/union_basic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
extern crate libcc2rs;
use libcc2rs::*;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::io::prelude::*;
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
#[derive(Default)]
pub struct basic {
pub i: Value<i32>,
pub f: Value<f32>,
}
impl ByteRepr for basic {}
pub fn main() {
std::process::exit(main_0());
}
fn main_0() -> i32 {
let u: Value<basic> = <Value<basic>>::default();
(*(*u.borrow()).i.borrow_mut()) = 42;
assert!(((*(*u.borrow()).i.borrow()) == 42));
(*(*u.borrow()).f.borrow_mut()) = 3.140000105E+0;
assert!(((*(*u.borrow()).f.borrow()) == 3.140000105E+0));
return 0;
}
26 changes: 26 additions & 0 deletions tests/unit/out/unsafe/union_basic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
extern crate libc;
use libc::*;
extern crate libcc2rs;
use libcc2rs::*;
use std::collections::BTreeMap;
use std::io::{Read, Seek, Write};
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
use std::rc::Rc;
#[derive(Copy, Clone, Default)]
pub struct basic {
pub i: i32,
pub f: f32,
}
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
}
}
unsafe fn main_0() -> i32 {
let mut u: basic = <basic>::default();
u.i = 42;
assert!(((u.i) == (42)));
u.f = 3.140000105E+0;
assert!(((u.f) == (3.140000105E+0)));
return 0;
}
49 changes: 49 additions & 0 deletions tests/unit/union_addrof_external.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// translation-fail
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

struct record {
uint16_t code;
uint16_t lo;
uint32_t hi;
char pad[8];
};

struct Container {
union {
struct record h;
char raw[128];
} view;
};

static void fill(void *out, size_t cap) {
unsigned char src[16] = {0};
src[0] = 2;
src[1] = 0;
src[2] = 0x00;
src[3] = 0x50;
src[4] = 0x7F;
src[5] = 0x00;
src[6] = 0x00;
src[7] = 0x01;
size_t n = sizeof(src) < cap ? sizeof(src) : cap;
memcpy(out, src, n);
}

int main(void) {
struct Container c;
memset(&c, 0, sizeof(c));

fill((void *)&c.view, sizeof(c.view));

assert(c.view.h.code == 2);
assert(((unsigned char *)&c.view.h.lo)[0] == 0x00);
assert(((unsigned char *)&c.view.h.lo)[1] == 0x50);

assert(c.view.raw[0] == 2);
assert((unsigned char)c.view.raw[3] == 0x50);

return 0;
}
18 changes: 18 additions & 0 deletions tests/unit/union_basic.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <assert.h>

union basic {
int i;
float f;
};

int main(void) {
union basic u;

u.i = 42;
assert(u.i == 42);

u.f = 3.14f;
assert(u.f == 3.14f);

return 0;
}
46 changes: 46 additions & 0 deletions tests/unit/union_cross_arm_cast.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// translation-fail
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

struct shape_a {
uint16_t code;
char pad[14];
};

struct shape_b {
uint16_t code;
uint16_t lo;
uint32_t mid;
uint8_t fill[16];
uint32_t tail;
};

struct Container {
unsigned int len;
union {
struct shape_a a;
struct shape_b b;
char raw[64];
} u;
};

int main(void) {
struct Container c;
memset(&c, 0, sizeof(c));

c.u.a.code = 10;
c.len = sizeof(struct shape_b);

((struct shape_b *)(void *)&c.u.a)->tail = 0xDEADBEEF;

assert(c.u.b.tail == 0xDEADBEEF);
assert(c.u.b.code == 10);

c.u.b.lo = 0x1F90;
assert(((unsigned char *)&c.u.raw)[2] == 0x90);
assert(((unsigned char *)&c.u.raw)[3] == 0x1F);

return 0;
}
22 changes: 22 additions & 0 deletions tests/unit/union_field_alignment.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// translation-fail
#include <assert.h>
#include <stddef.h>
#include <stdint.h>

// Just check if this compiles. node::x::aligner is used to impose a specific
// alignment on the bytes field.
struct node {
struct node *next;
union {
uint8_t bytes[1];
void *aligner;
} x;
};

int main(void) {
struct node n;
n.next = 0;
n.x.bytes[0] = 0xAB;
assert(n.x.bytes[0] == 0xAB);
return 0;
}
35 changes: 35 additions & 0 deletions tests/unit/union_flex_array_member.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// translation-fail
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

struct node {
size_t len;
union {
uint8_t bytes[1];
void *aligner;
} x;
};

int main(void) {
size_t tail_size = 32;
struct node *n = (struct node *)malloc(sizeof(struct node) + tail_size);
n->len = tail_size;

for (size_t i = 0; i < tail_size; i++) {
n->x.bytes[i] = (uint8_t)(i & 0xFF);
}
for (size_t i = 0; i < tail_size; i++) {
assert(n->x.bytes[i] == (uint8_t)(i & 0xFF));
}

uint8_t *p = &n->x.bytes[10];
assert(*p == 10);
*p = 0xAA;
assert(n->x.bytes[10] == 0xAA);

free(n);
return 0;
}
55 changes: 55 additions & 0 deletions tests/unit/union_memset_memcpy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// translation-fail
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

struct shape_a {
uint16_t code;
char pad[14];
};

struct shape_b {
uint16_t code;
uint16_t lo;
uint32_t hi;
char fill[8];
};

struct Container {
union {
struct shape_a a;
struct shape_b b;
char raw[256];
} view;
};

int main(void) {
struct Container c;

memset(&c, 0, sizeof(c));
assert(c.view.a.code == 0);
assert(c.view.b.lo == 0);
assert(c.view.raw[0] == 0);
assert(c.view.raw[255] == 0);

unsigned char src[16] = {0};
src[0] = 2;
src[2] = 0x50;
src[3] = 0x00;
src[4] = 0x7F;
src[5] = 0x00;
src[6] = 0x00;
src[7] = 0x01;
size_t len = 16;
assert(len <= sizeof(c.view.raw));
memcpy(&c.view.raw, src, len);

assert(c.view.b.code == 2);
assert(((unsigned char *)&c.view.b.lo)[0] == 0x50);

memset(&c, 0, sizeof(c));
assert(c.view.b.code == 0);

return 0;
}
45 changes: 45 additions & 0 deletions tests/unit/union_nested.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// translation-fail
#include <assert.h>
#include <stdint.h>
#include <string.h>

struct record {
uint16_t code;
char pad[14];
};

struct inner {
union {
struct record h;
char raw[128];
} view;
};

struct Outer {
int kind;
int level;
int variant;
unsigned int len;
union {
struct record h;
struct inner nested;
} body;
};

int main(void) {
struct Outer ex;
memset(&ex, 0, sizeof(ex));

ex.kind = 2;
ex.level = 1;
ex.variant = 6;
ex.len = sizeof(struct record);
ex.body.h.code = 2;
ex.body.h.pad[0] = 'X';

assert(ex.body.h.code == 2);
assert(ex.body.h.pad[0] == 'X');

assert(ex.body.nested.view.h.code == 2);
return 0;
}
26 changes: 26 additions & 0 deletions tests/unit/union_pointer_pun_address.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// translation-fail
#include <assert.h>

struct node_a {
int n;
};

struct node_b {
void *data;
struct node_b *next;
};

int main(void) {
struct node_a a = {123};

union {
struct node_a *to_a;
struct node_b *to_b;
} ptr;

ptr.to_a = &a;
struct node_b *out = ptr.to_b;

assert((void *)out == (void *)&a);
return 0;
}
17 changes: 17 additions & 0 deletions tests/unit/union_pointer_pun_writethrough.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// translation-fail
#include <assert.h>

int main(void) {
long x = -1;

union {
unsigned long *as_unsigned;
long *as_signed;
} pp;

pp.as_signed = &x;
*pp.as_unsigned = 42UL;

assert(x == 42);
return 0;
}
Loading
Loading