From: Simon Marchi Date: Fri, 30 Jul 2021 03:06:11 +0000 (-0400) Subject: Make temporary variable in _rcu_dereference non-const X-Git-Tag: v0.14.0~71 X-Git-Url: https://git.liburcu.org/?p=urcu.git;a=commitdiff_plain;h=1e41ec3b07e4f8eb71c3ace758c76a7ad1784c73 Make temporary variable in _rcu_dereference non-const When building the lttng-tools project with Ubuntu's gcc 11, I get the following error: CC agent.lo In file included from /tmp/lttng/include/urcu/arch.h:25, from /tmp/lttng/include/urcu/uatomic.h:23, from /home/simark/src/lttng-tools/src/bin/lttng-sessiond/agent.c:11: /home/simark/src/lttng-tools/src/bin/lttng-sessiond/agent.c: In function ‘agent_update’: /tmp/lttng/include/urcu/static/pointer.h:96:33: error: argument 2 of ‘__atomic_load’ discards ‘const’ qualifier [-Werror=incompatible-pointer-types] 96 | __atomic_load(&(p), &_________p1, __ATOMIC_CONSUME); \ | ^~~~~~~~~~~~~ /tmp/lttng/include/urcu/compiler.h:69:70: note: in definition of macro ‘caa_container_of’ 69 | const __typeof__(((type *) NULL)->member) * __ptr = (ptr); \ | ^~~ /tmp/lttng/include/urcu/rculist.h:87:20: note: in expansion of macro ‘cds_list_entry’ 87 | for (pos = cds_list_entry(rcu_dereference((head)->next), __typeof__(*(pos)), member); \ | ^~~~~~~~~~~~~~ /tmp/lttng/include/urcu/pointer.h:47:33: note: in expansion of macro ‘_rcu_dereference’ 47 | #define rcu_dereference _rcu_dereference | ^~~~~~~~~~~~~~~~ /tmp/lttng/include/urcu/rculist.h:87:35: note: in expansion of macro ‘rcu_dereference’ 87 | for (pos = cds_list_entry(rcu_dereference((head)->next), __typeof__(*(pos)), member); \ | ^~~~~~~~~~~~~~~ /home/simark/src/lttng-tools/src/bin/lttng-sessiond/agent.c:1551:9: note: in expansion of macro ‘cds_list_for_each_entry_rcu’ 1551 | cds_list_for_each_entry_rcu(ctx, &agt->app_ctx_list, list_node) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ This is because the pointer passed to _rcu_dereference is const (the pointer itself is const, IIUC, not necessarily the data it points to), so the temporary _________p1 is also declared as const. We therefore can't pass a non-const pointer to it to a function that modifies it. I applied the trick found here [1] with success to get rid of the constness of the variable. With this change, lttng-tools compiles successfully with gcc 11. There may be other spots in the headers where this would be needed, but it is hard to spot them. I think we would need to write some test file that pass const pointers to all macros of the API and see if they compile. [1] https://stackoverflow.com/a/18067745 Signed-off-by: Simon Marchi Signed-off-by: Mathieu Desnoyers Change-Id: Ib43efa7674ecea99cec1c3fffae86829b44a97e5 --- diff --git a/include/urcu/static/pointer.h b/include/urcu/static/pointer.h index ca9a2f9..465a610 100644 --- a/include/urcu/static/pointer.h +++ b/include/urcu/static/pointer.h @@ -90,9 +90,15 @@ extern "C" { # define __URCU_DEREFERENCE_USE_ATOMIC_CONSUME #endif +/* + * If p is const (the pointer itself, not what it points to), using + * __typeof__(p) would declare a const variable, leading to + * -Wincompatible-pointer-types errors. Using `+ 0` makes it an rvalue and + * gets rid of the const-ness. + */ #ifdef __URCU_DEREFERENCE_USE_ATOMIC_CONSUME # define _rcu_dereference(p) __extension__ ({ \ - __typeof__(p) _________p1; \ + __typeof__(p + 0) _________p1; \ __atomic_load(&(p), &_________p1, __ATOMIC_CONSUME); \ (_________p1); \ })