C11 disallows calling atomic_load with const pointers
Summary
Building BIND with a C compiler that strictly complies with C11 will fail on the find_server_request_handler
function and some calls to the VALID_NMHANDLE
macro, due to them calling atomic_load with const pointers. This only became allowed in C17: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2244.htm#dr_459
BIND version used
BIND 9.18.3 (Stable Release) id:16aefa3
Steps to reproduce
Build BIND with a C compiler that implements C11 but not the C17 fixes, such as Apple clang-1000.11.45.5.
What is the current bug behavior?
Build fails.
What is the expected correct behavior?
Build succeeds.
Relevant configuration files
N/A
Relevant logs and/or screenshots
netmgr/http.c:1656:6: error: address argument to atomic operation must be a pointer to non-const _Atomic type ('const atomic_bool *' (aka 'const _Atomic(bool) *') invalid)
if (atomic_load(&serversocket->listening)) {
^ ~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/lib/clang/10.0.0/include/stdatomic.h:134:29: note: expanded from macro 'atomic_load'
#define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST)
^ ~~~~~~
netmgr/http.c:2903:10: error: address argument to atomic operation must be a pointer to non-const _Atomic type ('const isc_refcount_t *' (aka 'const _Atomic(uint_fast32_t) *') invalid)
REQUIRE(VALID_NMHANDLE(handle));
~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
netmgr/netmgr-int.h:247:3: note: expanded from macro 'VALID_NMHANDLE'
atomic_load(&(t)->references) > 0)
^
/Library/Developer/CommandLineTools/usr/lib/clang/10.0.0/include/stdatomic.h:134:29: note: expanded from macro 'atomic_load'
#define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST)
^
Possible fixes
I was able to work around the problem by casting the offending pointers to non-const, but that's a pretty horrible approach.
--- ./lib/isc/netmgr/netmgr-int.h.orig 2022-01-24 19:28:57.000000000 +1100
+++ ./lib/isc/netmgr/netmgr-int.h 2022-02-19 02:03:23.000000000 +1100
@@ -233,7 +233,7 @@ typedef struct isc__networker {
#define NMHANDLE_MAGIC ISC_MAGIC('N', 'M', 'H', 'D')
#define VALID_NMHANDLE(t) \
(ISC_MAGIC_VALID(t, NMHANDLE_MAGIC) && \
- atomic_load(&(t)->references) > 0)
+ atomic_load((isc_refcount_t *)&(t)->references) > 0)
typedef void (*isc__nm_closecb)(isc_nmhandle_t *);
typedef struct isc_nm_http_session isc_nm_http_session_t;
--- lib/isc/netmgr/http.c.orig 2022-01-24 19:28:57.000000000 +1100
+++ lib/isc/netmgr/http.c 2022-02-19 02:13:12.000000000 +1100
@@ -1651,7 +1651,7 @@ find_server_request_handler(const char *
REQUIRE(VALID_NMSOCK(serversocket));
- if (atomic_load(&serversocket->listening)) {
+ if (atomic_load((atomic_bool *)&serversocket->listening)) {
handler = http_endpoints_find(
request_path, serversocket->h2.listener_endpoints);
}