[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH for-4.9 v3 2/3] x86/atomic: fix clang build
The current code in dm_op breaks clang build with: dm.c:411:21: error: 'break' is bound to loop, GCC binds it to switch [-Werror,-Wgcc-compat] while ( read_atomic(&p2m->ioreq.entry_count) && ^ xen/include/asm/atomic.h:53:43: note: expanded from macro 'read_atomic' default: x_ = 0; __bad_atomic_size(); break; \ ^ Introduce a readatomic static inline helper function in order to solve this. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- Cc: Jan Beulich <jbeulich@xxxxxxxx> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- Changes since v2: - Introduce a readatomic static inline helper in order to prevent moving the read_atomic check. Changes since v1: - New in this version. --- xen/include/asm-x86/atomic.h | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/xen/include/asm-x86/atomic.h b/xen/include/asm-x86/atomic.h index 2fbe705518..ae87a0dcf5 100644 --- a/xen/include/asm-x86/atomic.h +++ b/xen/include/asm-x86/atomic.h @@ -41,20 +41,42 @@ build_add_sized(add_u64_sized, "q", uint64_t, "ri") #undef build_write_atomic #undef build_add_sized -void __bad_atomic_size(void); +/* + * NB: read_atomic needs to be a static inline function because clang doesn't + * like breaks inside of expressions, even when there's an inner switch where + * those breaks should apply, and complains with "'break' is bound to loop, GCC + * binds it to switch", so the following code: + * + * while ( read_atomic(&foo) ) { ... } + * + * Doesn't work if read_atomic is a macro with an inner switch. + */ +static inline unsigned long readatomic(const void *p, size_t s) +{ + switch ( s ) + { + case 1: + return read_u8_atomic((uint8_t *)p); + case 2: + return read_u16_atomic((uint16_t *)p); + case 4: + return read_u32_atomic((uint32_t *)p); + case 8: + return read_u64_atomic((uint64_t *)p); + default: + ASSERT_UNREACHABLE(); + return 0; + } +} -#define read_atomic(p) ({ \ - unsigned long x_; \ - switch ( sizeof(*(p)) ) { \ - case 1: x_ = read_u8_atomic((uint8_t *)(p)); break; \ - case 2: x_ = read_u16_atomic((uint16_t *)(p)); break; \ - case 4: x_ = read_u32_atomic((uint32_t *)(p)); break; \ - case 8: x_ = read_u64_atomic((uint64_t *)(p)); break; \ - default: x_ = 0; __bad_atomic_size(); break; \ - } \ - (typeof(*(p)))x_; \ +#define read_atomic(p) ({ \ + BUILD_BUG_ON(sizeof(*(p)) != 1 && sizeof(*(p)) != 2 && \ + sizeof(*(p)) != 4 && sizeof(*(p)) != 8); \ + (typeof(*(p)))readatomic(p, sizeof(*(p))); \ }) +void __bad_atomic_size(void); + #define write_atomic(p, x) ({ \ typeof(*(p)) __x = (x); \ unsigned long x_ = (unsigned long)__x; \ -- 2.11.0 (Apple Git-81) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |