Skip to content

Use Rust union types #2056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
96 changes: 2 additions & 94 deletions libc-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,6 @@ fn test_apple(target: &str) {
return true;
}
match ty {
// FIXME: actually a union
"sigval" => true,

// FIXME: The size is changed in recent macOSes.
"malloc_zone_t" => true,
// it is a moving target, changing through versions
Expand Down Expand Up @@ -423,14 +420,6 @@ fn test_apple(target: &str) {
}
});

cfg.skip_field_type(move |struct_, field| {
match (struct_, field) {
// FIXME: actually a union
("sigevent", "sigev_value") => true,
_ => false,
}
});

cfg.volatile_item(|i| {
use ctest::VolatileItemKind::*;
match i {
Expand Down Expand Up @@ -570,27 +559,6 @@ fn test_openbsd(target: &str) {
"sys/param.h",
}

cfg.skip_struct(move |ty| {
if ty.starts_with("__c_anonymous_") {
return true;
}
match ty {
// FIXME: actually a union
"sigval" => true,

_ => false,
}
});

cfg.skip_const(move |name| {
match name {
// Removed in OpenBSD 7.7 (unused since 1991)
"ATF_COM" | "ATF_PERM" | "ATF_PUBL" | "ATF_USETRAILERS" => true,

_ => false,
}
});

cfg.skip_fn(move |name| {
match name {
// futex() has volatile arguments, but that doesn't exist in Rust.
Expand Down Expand Up @@ -938,8 +906,6 @@ fn test_solarish(target: &str) {

cfg.field_name(move |struct_, field| {
match struct_ {
// rust struct uses raw u64, rather than union
"epoll_event" if field == "u64" => "data.u64".to_string(),
// rust struct was committed with typo for Solaris
"door_arg_t" if field == "dec_num" => "desc_num".to_string(),
"stat" if field.ends_with("_nsec") => {
Expand Down Expand Up @@ -985,8 +951,6 @@ fn test_solarish(target: &str) {
return true;
}
match ty {
// union, not a struct
"sigval" => true,
// a bunch of solaris-only fields
"utmpx" if is_illumos => true,
_ => false,
Expand All @@ -1006,8 +970,6 @@ fn test_solarish(target: &str) {
"sigaction" if field == "sa_sigaction" => true,
// Missing in illumos
"sigevent" if field == "ss_sp" => true,
// Avoid sigval union issues
"sigevent" if field == "sigev_value" => true,
// const issues
"sigevent" if field == "sigev_notify_attributes" => true,

Expand Down Expand Up @@ -1212,7 +1174,6 @@ fn test_netbsd(target: &str) {
s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
s.replace("e_nsec", ".tv_nsec")
}
"u64" if struct_ == "epoll_event" => "data.u64".to_string(),
s => s.to_string(),
}
});
Expand All @@ -1230,8 +1191,6 @@ fn test_netbsd(target: &str) {

cfg.skip_struct(move |ty| {
match ty {
// This is actually a union, not a struct
"sigval" => true,
// These are tested as part of the linux_fcntl tests since there are
// header conflicts when including them with all the other structs.
"termios2" => true,
Expand Down Expand Up @@ -1282,8 +1241,6 @@ fn test_netbsd(target: &str) {
(struct_ == "ifaddrs" && field == "ifa_ifu") ||
// sighandler_t type is super weird
(struct_ == "sigaction" && field == "sa_sigaction") ||
// sigval is actually a union, but we pretend it's a struct
(struct_ == "sigevent" && field == "sigev_value") ||
// aio_buf is "volatile void*" and Rust doesn't understand volatile
(struct_ == "aiocb" && field == "aio_buf")
});
Expand Down Expand Up @@ -1412,9 +1369,6 @@ fn test_dragonflybsd(target: &str) {

t if t.ends_with("_t") => t.to_string(),

// sigval is a struct in Rust, but a union in C:
"sigval" => format!("union sigval"),

// put `struct` in front of all structs:.
t if is_struct => format!("struct {}", t),

Expand All @@ -1429,7 +1383,6 @@ fn test_dragonflybsd(target: &str) {
s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
s.replace("e_nsec", ".tv_nsec")
}
"u64" if struct_ == "epoll_event" => "data.u64".to_string(),
// Field is named `type` in C but that is a Rust keyword,
// so these fields are translated to `type_` in the bindings.
"type_" if struct_ == "rtprio" => "type".to_string(),
Expand Down Expand Up @@ -1507,8 +1460,6 @@ fn test_dragonflybsd(target: &str) {
(struct_ == "ifaddrs" && field == "ifa_ifu") ||
// sighandler_t type is super weird
(struct_ == "sigaction" && field == "sa_sigaction") ||
// sigval is actually a union, but we pretend it's a struct
(struct_ == "sigevent" && field == "sigev_value") ||
// aio_buf is "volatile void*" and Rust doesn't understand volatile
(struct_ == "aiocb" && field == "aio_buf")
});
Expand Down Expand Up @@ -1799,9 +1750,6 @@ fn test_android(target: &str) {

t if t.ends_with("_t") => t.to_string(),

// sigval is a struct in Rust, but a union in C:
"sigval" => format!("union sigval"),

// put `struct` in front of all structs:.
t if is_struct => format!("struct {}", t),

Expand All @@ -1814,8 +1762,6 @@ fn test_android(target: &str) {
// Our stat *_nsec fields normally don't actually exist but are part
// of a timeval struct
s if s.ends_with("_nsec") && struct_.starts_with("stat") => s.to_string(),
// FIXME: appears that `epoll_event.data` is an union
"u64" if struct_ == "epoll_event" => "data.u64".to_string(),
// The following structs have a field called `type` in C,
// but `type` is a Rust keyword, so these fields are translated
// to `type_` in Rust.
Expand Down Expand Up @@ -2096,8 +2042,6 @@ fn test_android(target: &str) {
cfg.skip_field_type(move |struct_, field| {
// This is a weird union, don't check the type.
(struct_ == "ifaddrs" && field == "ifa_ifu") ||
// sigval is actually a union, but we pretend it's a struct
(struct_ == "sigevent" && field == "sigev_value") ||
// this one is an anonymous union
(struct_ == "ff_effect" && field == "u") ||
// FIXME: `sa_sigaction` has type `sighandler_t` but that type is
Expand Down Expand Up @@ -2306,9 +2250,6 @@ fn test_freebsd(target: &str) {

t if t.ends_with("_t") => t.to_string(),

// sigval is a struct in Rust, but a union in C:
"sigval" => format!("union sigval"),

// put `struct` in front of all structs:.
t if is_struct => format!("struct {}", t),

Expand Down Expand Up @@ -2901,8 +2842,6 @@ fn test_emscripten(target: &str) {
s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
s.replace("e_nsec", ".tv_nsec")
}
// Rust struct uses raw u64, rather than union
"u64" if struct_ == "epoll_event" => "data.u64".to_string(),
s => s.to_string(),
}
});
Expand All @@ -2928,9 +2867,6 @@ fn test_emscripten(target: &str) {
return true;
}
match ty {
// This is actually a union, not a struct
"sigval" => true,

// FIXME: Investigate why the test fails.
// Skip for now to unblock CI.
"pthread_condattr_t" => true,
Expand Down Expand Up @@ -3006,9 +2942,7 @@ fn test_emscripten(target: &str) {
// This is a weird union, don't check the type.
(struct_ == "ifaddrs" && field == "ifa_ifu") ||
// sighandler_t type is super weird
(struct_ == "sigaction" && field == "sa_sigaction") ||
// sigval is actually a union, but we pretend it's a struct
(struct_ == "sigevent" && field == "sigev_value")
(struct_ == "sigaction" && field == "sa_sigaction")
});

cfg.skip_field(move |struct_, field| {
Expand Down Expand Up @@ -3204,9 +3138,6 @@ fn test_neutrino(target: &str) {
match ty {
"Elf64_Phdr" | "Elf32_Phdr" => true,

// FIXME(union): This is actually a union, not a struct
"sigval" => true,

// union
"_channel_connect_attr" => true,

Expand Down Expand Up @@ -3258,8 +3189,6 @@ fn test_neutrino(target: &str) {
});

cfg.skip_field_type(move |struct_, field| {
// sigval is actually a union, but we pretend it's a struct
struct_ == "sigevent" && field == "sigev_value" ||
// Anonymous structures
struct_ == "_idle_hook" && field == "time"
});
Expand All @@ -3268,8 +3197,6 @@ fn test_neutrino(target: &str) {
(struct_ == "__sched_param" && field == "reserved") ||
(struct_ == "sched_param" && field == "reserved") ||
(struct_ == "sigevent" && field == "__padding1") || // ensure alignment
(struct_ == "sigevent" && field == "__padding2") || // union
(struct_ == "sigevent" && field == "__sigev_un2") || // union
// sighandler_t type is super weird
(struct_ == "sigaction" && field == "sa_sigaction") ||
// does not exist
Expand Down Expand Up @@ -3378,10 +3305,8 @@ fn test_vxworks(target: &str) {

// FIXME(vxworks)
cfg.skip_fn(move |name| match name {
// sigval
"sigqueue" | "_sigqueue"
// sighandler_t
| "signal"
"signal"
// not used in static linking by default
| "dlerror" => true,
_ => false,
Expand Down Expand Up @@ -3652,10 +3577,6 @@ fn test_linux(target: &str) {
s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
s.replace("e_nsec", ".tv_nsec")
}
// FIXME(linux): epoll_event.data is actually a union in C, but in Rust
// it is only a u64 because we only expose one field
// http://man7.org/linux/man-pages/man2/epoll_wait.2.html
"u64" if struct_ == "epoll_event" => "data.u64".to_string(),
// The following structs have a field called `type` in C,
// but `type` is a Rust keyword, so these fields are translated
// to `type_` in Rust.
Expand Down Expand Up @@ -3770,9 +3691,6 @@ fn test_linux(target: &str) {
// which is absent in glibc, has to be defined.
"__timeval" => true,

// FIXME(union): This is actually a union, not a struct
"sigval" => true,

// This type is tested in the `linux_termios.rs` file since there
// are header conflicts when including them with all the other
// structs.
Expand Down Expand Up @@ -4374,8 +4292,6 @@ fn test_linux(target: &str) {
(struct_ == "sigaction" && field == "sa_sigaction") ||
// __timeval type is a patch which doesn't exist in glibc
(struct_ == "utmpx" && field == "ut_tv") ||
// sigval is actually a union, but we pretend it's a struct
(struct_ == "sigevent" && field == "sigev_value") ||
// this one is an anonymous union
(struct_ == "ff_effect" && field == "u") ||
// `__exit_status` type is a patch which is absent in musl
Expand Down Expand Up @@ -4482,8 +4398,6 @@ fn test_linux(target: &str) {
cfg.skip_roundtrip(move |s| match s {
// FIXME:
"mcontext_t" if s390x => true,
// FIXME: This is actually a union.
"fpreg_t" if s390x => true,

// The test doesn't work on some env:
"ipv6_mreq"
Expand Down Expand Up @@ -4847,8 +4761,6 @@ fn test_haiku(target: &str) {
return true;
}
match ty {
// FIXME: actually a union
"sigval" => true,
// FIXME: locale_t does not exist on Haiku
"locale_t" => true,
// FIXME: rusage has a different layout on Haiku
Expand Down Expand Up @@ -4955,10 +4867,8 @@ fn test_haiku(target: &str) {
("stat", "st_crtime_nsec") => true,

// these are actually unions, but we cannot represent it well
("siginfo_t", "sigval") => true,
("sem_t", "named_sem_id") => true,
("sigaction", "sa_sigaction") => true,
("sigevent", "sigev_value") => true,
("fpu_state", "_fpreg") => true,
("cpu_topology_node_info", "data") => true,
// these fields have a simplified data definition in libc
Expand Down Expand Up @@ -5009,8 +4919,6 @@ fn test_haiku(target: &str) {
ty.to_string()
}

// is actually a union
"sigval" => format!("union sigval"),
t if is_union => format!("union {}", t),
t if t.ends_with("_t") => t.to_string(),
t if is_struct => format!("struct {}", t),
Expand Down
Loading
Loading