-
-
Notifications
You must be signed in to change notification settings - Fork 652
Description
On FreeBSD 14, dmd-test fails with
FAILED targets:
- runnable/helloc.c
- compilable/stdcheaders.c
gmake: *** [Makefile:86: dmd-test] Error 1
Both of those files #include stdlib.h, so while the actual error isn't given, I'm pretty sure that the issue here is that dmd can't handle gnu assembly, and stdlib.h uses gnu assembly on FreeBSD 14 (but not 13, which is why the FreeBSD 13 tests do not fail with this problem in the CI), since if you write a test that tries to use importC on stdlib.h on FreeBSD 14, it will fail for that reason. Specifically, it's this section of stdlib.h that's the problem:
/*
* In FreeBSD 14, the prototype of qsort_r() was modified to comply with
* POSIX. The standardized qsort_r()'s order of last two parameters was
* changed, and the comparator function is now taking thunk as its last
* parameter, and both are different from the ones expected by the historical
* FreeBSD qsort_r() interface.
*
* Apply a workaround where we explicitly link against the historical
* interface, qsort_r@FBSD_1.0, in case when qsort_r() is called with
* the last parameter with a function pointer that exactly matches the
* historical FreeBSD qsort_r() comparator signature, so applications
* written for the historical interface can continue to work without
* modification.
*/
#if defined(__generic) || defined(__cplusplus)
void __qsort_r_compat(void *, size_t, size_t, void *,
int (*)(void *, const void *, const void *));
__sym_compat(qsort_r, __qsort_r_compat, FBSD_1.0);
#endif
#if defined(__generic) && !defined(__cplusplus)
#define qsort_r(base, nel, width, arg4, arg5) \
__generic(arg5, int (*)(void *, const void *, const void *), \
__qsort_r_compat, qsort_r)(base, nel, width, arg4, arg5)
#elif defined(__cplusplus)
__END_DECLS
extern "C++" {
static inline void qsort_r(void *base, size_t nmemb, size_t size,
void *thunk, int (*compar)(void *, const void *, const void *)) {
__qsort_r_compat(base, nmemb, size, thunk, compar);
}
}
I'm not sure which version of the __sym_compat
macro from sys/cdefs.h is compiled in, either
#define __sym_compat(sym,impl,verid) \
__asm__(".symver " #impl ", " #sym "@" #verid)
or
#define __sym_compat(sym,impl,verid) \
__asm__(".symver impl, sym@verid")
but either way, a gnu assembly instruction is being used, and dmd errors out when it encounters it.
So, in order for FreeBSD 14 to pass the dmd test suite, either dmd needs to actually learn to handle gnu assembly at least far enough to compile stdlib.h rather than choking on the assembly instruction, or the tests are going to need to be changed to not use importC on stdlib.h on FreeBSD.
#20607 is essentially the same issue except for the druntime tests, though obviously, the fix is different if the tests are going to be changed rather than improving dmd's capabilities to actually be able to handle stdlib.h on FreeBSD 14.
Personally, I'd really like it if dmd could actually compile code that uses gnu assembly code even if it's simply by skipping any symbols that have gnu assembly on them. This is not the first time that FreeBSD has used gnu assembly in such a fashion in system headers, and it likely won't be the last. And given how common gnu assembly is, it can't be all that uncommon for C headers to use it somewhere, which is going to cause problems with importC as things stand. Of course, the ideal situation would be if dmd could actually compile the assembly code properly like ldc or gdc would be able to do, but presumably, that's a large undertaking.
Either way, the handling of stdlib.h and importC needs to be sorted out somehow, or we won't be able to update the CI to test FreeBSD 14. The expected EoL for FreeBSD 13 is in April of next year.