Skip to content

Commit e2d90cd

Browse files
committed
Auto merge of #3254 - bossmc:flexible-array-members, r=JohnTitor
Skip round-trip tests for structs with FAMs For example: ``` strcut inotify_event { int wd; /* Watch descriptor */ uint32_t mask; /* Mask describing event */ uint32_t cookie; /* Unique cookie associating related events (for rename(2)) */ uint32_t len; /* Size of name field */ char name[]; /* Optional null-terminated name */ }; ``` the `name` field at the end of this struct is a Flexible Array Member (FAM - https://en.wikipedia.org/wiki/Flexible_array_member) and represents an inline array of _some_ length (in this case the `len` field gives the length, but FAMs in general are unsized). These forms cause problems in two ways: 1. There's no rust-equivalent for FAM-containing structs (see rust-lang/rfcs#3396 for details) - the current approach is just to omit the `name` field in the Rust representation. 2. These structs cannot be passed by value (basically the compiler cannot know how many elements of the `name` field should be copied) and different compilers do different things when asked to do so. This PR focusses on the second of these problems since it was causing test failures on my machine. If you run the libc-test suite with GCC as your C compiler you get a compiler note saying the following: ``` /out/main.c: In function ‘__test_roundtrip_inotify_event’: /out/main.c:21011:13: note: the ABI of passing struct with a flexible array member has changed in GCC 4.4 ``` and the test suite passes. OTOH if you build with clang as your compiler you get no compile time warnings/errors but the test suite fails: ``` size of struct inotify_event is 16 in C and 185207048 in Rust error: test failed, to rerun pass `--test main` Caused by: process didn't exit successfully: `/deps/main-e32ea4d2acb868af` (signal: 11, SIGSEGV: invalid memory reference) ``` (note that 185207048 is `0x08090A0B` (which is what the round-tripped value is initialized with by the test suite) so clearly the Rust and C code are disagreeing about the calling convention/register layout when passing such a struct). Given that there doesn't seem to be a specification for passing these objects by value, this PR simply omits them from the roundtrip tests and the test suite now passes on GCC _and_ clang without warnings.
2 parents 0d78fe1 + f8e82dc commit e2d90cd

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

libc-test/build.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -3333,15 +3333,15 @@ fn test_linux(target: &str) {
33333333
"Ioctl" if gnu => "unsigned long".to_string(),
33343334
"Ioctl" => "int".to_string(),
33353335

3336-
t if is_union => format!("union {}", t),
3337-
3338-
t if t.ends_with("_t") => t.to_string(),
3339-
33403336
// In MUSL `flock64` is a typedef to `flock`.
33413337
"flock64" if musl => format!("struct {}", ty),
33423338

3339+
// typedefs don't need any keywords
3340+
t if t.ends_with("_t") => t.to_string(),
33433341
// put `struct` in front of all structs:.
33443342
t if is_struct => format!("struct {}", t),
3343+
// put `union` in front of all unions:
3344+
t if is_union => format!("union {}", t),
33453345

33463346
t => t.to_string(),
33473347
}
@@ -3390,7 +3390,8 @@ fn test_linux(target: &str) {
33903390
// on Linux, this is a volatile int
33913391
"pthread_spinlock_t" => true,
33923392

3393-
// For internal use only, to define architecture specific ioctl constants with a libc specific type.
3393+
// For internal use only, to define architecture specific ioctl constants with a libc
3394+
// specific type.
33943395
"Ioctl" => true,
33953396

33963397
// FIXME: requires >= 5.4.1 kernel headers
@@ -3964,6 +3965,13 @@ fn test_linux(target: &str) {
39643965
true
39653966
}
39663967

3968+
// The `inotify_event` and `cmsghdr` types contain Flexible Array Member fields (the
3969+
// `name` and `data` fields respectively) which have unspecified calling convention.
3970+
// The roundtripping tests deliberately pass the structs by value to check "by value"
3971+
// layout consistency, but this would be UB for the these types.
3972+
"inotify_event" => true,
3973+
"cmsghdr" => true,
3974+
39673975
// FIXME: the call ABI of max_align_t is incorrect on these platforms:
39683976
"max_align_t" if i686 || mips64 || ppc64 => true,
39693977

0 commit comments

Comments
 (0)