GHC 9.4.4 `Rts.h` fails to compile after `rts/PosixSource.h` on FreeBSD 12.3
Summary
As of commit d2ea5bfb Rts.h
attempts to use static_assert()
:
+/* For _Static_assert */
+#include <assert.h>
...
+#if __STDC_VERSION__ >= 201112L
+#define GHC_STATIC_ASSERT(x, msg) static_assert((x), msg)
+#else
+#define GHC_STATIC_ASSERT(x, msg)
+#endif
But in code generated from derivedConstants
the order of #include
files is:
#include "rts/PosixSource.h"
#include "Rts.h"
...
which defines _POSIX_SOURCE
on FreeBSD systems, which blocks the visibility of the C23 static_assert()
(only the C11 original _Static_assert()
is defined). The <assert.h>
file on FreeBSD 12 reads in part:
/*
* Static assertions. In principle we could define static_assert for
* C++ older than C++11, but this breaks if _Static_assert is
* implemented as a macro.
*
* C++ template parameters may contain commas, even if not enclosed in
* parentheses, causing the _Static_assert macro to be invoked with more
* than two parameters.
*/
#if __ISO_C_VISIBLE >= 2011 && !defined(__cplusplus)
#define static_assert _Static_assert
#endif
has static_assert
conditional on __ISO_C_VISIBLE
, and that macro is hidden when _POSIX_SOURCE
is defined. From <sys/cdefs.h>
:
#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
# define _POSIX_C_SOURCE 198808
#endif
#ifdef _POSIX_C_SOURCE
# if _POSIX_C_SOURCE >= 200809
# define __POSIX_VISIBLE 200809
# define __ISO_C_VISIBLE 1999
# elif /* ... various older variants ... */
# ...
# endif /* _POSIX_C_SOURCE */
#else
/*-
* Deal with _ANSI_SOURCE:
...
*/
# if defined(_ANSI_SOURCE) /* Hide almost everything. */
# define __POSIX_VISIBLE 0
# define __XSI_VISIBLE 0
# define __BSD_VISIBLE 0
# define __ISO_C_VISIBLE 1990
# define __EXT1_VISIBLE 0
# elif defined(_C99_SOURCE) /* Localism to specify strict C99 env. */
# define __POSIX_VISIBLE 0
# define __XSI_VISIBLE 0
# define __BSD_VISIBLE 0
# define __ISO_C_VISIBLE 1999
# define __EXT1_VISIBLE 0
# elif defined(_C11_SOURCE) /* Localism to specify strict C11 env. */
# define __POSIX_VISIBLE 0
# define __XSI_VISIBLE 0
# define __BSD_VISIBLE 0
# define __ISO_C_VISIBLE 2011
# define __EXT1_VISIBLE 0
# else /* Default environment: show everything. */
# define __POSIX_VISIBLE 200809
# define __XSI_VISIBLE 700
# define __BSD_VISIBLE 1
# define __ISO_C_VISIBLE 2011
# define __EXT1_VISIBLE 1
# endif
#endif
Bottom line __ISO_C_VISIBLE
is set to 2011
only if none of the various standards-compliance _FOO_SOURCE
macros are defined. As a result the code generated by deriveConstants
fails to compile:
Command line: .../deriveConstants --gen-header -o .../stage1/rts/build/include/DerivedConstants.h --tmpdir /tmp/extra-dir-51880349607072 --gcc-program /usr/local/bin/gcc10 --gcc-flag -Wall --gcc-flag -Werror=unused-but-set-variable --gcc-flag -Wno-error=inline --gcc-flag -Irts --gcc-flag -Irts/include --gcc-flag -I.../stage1/rts/build/include --gcc-flag -fcommon --nm-program /usr/local/bin/nm --objdump-program /usr/local/bin/objdump --target-os freebsd
===> Command failed with error code: 1
In file included from /tmp/extra-dir-51880349607072/tmp.c:14:
rts/include/Rts.h:170:49: error: expected declaration specifiers or '...' before '(' token
170 | #define GHC_STATIC_ASSERT(x, msg) static_assert((x), msg)
| ^
Possible work-arounds:
- Continue to use
_Static_assert
. - Include
<assert.h>
first. - Avoid the static assertion on FreeBSD 12
Steps to reproduce
Attempt to build GHC 9.4.4 on FreeBSD 12.3.
Expected behavior
GHC 9.4.4 should build
Environment
- GHC version used: 9.4.4
Optional:
- Operating System: FreeBSD 12.3
- System Architecture: x86_64