From 637f7fe16e11118f33e23abd63469229d6df6e08 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Thu, 24 Nov 2016 20:13:06 +0300 Subject: [PATCH] Workaround a bug in double-wide intrinsics of Clang/x64 with ASan enabled As of clang-3.8, double-wide arguments are incorrectly passed to atomic intrinsic operations for x64 target if Address Sanitizer is enabled. * src/atomic_ops.h [__has_feature(address_sanitizer)] (AO_ADDRESS_SANITIZER): New internal macro. * src/atomic_ops/sysdeps/gcc/x86.h [AO_GCC_ATOMIC_TEST_AND_SET && __clang__ && __x86_64__ && !__ILP32__] (AO_SKIPATOMIC_double_compare_and_swap_ANY, AO_SKIPATOMIC_double_load, AO_SKIPATOMIC_double_load_acquire, AO_SKIPATOMIC_double_store, AO_SKIPATOMIC_double_store_release): Define also if AO_ADDRESS_SANITIZER; update comment. --- src/atomic_ops.h | 7 +++++++ src/atomic_ops/sysdeps/gcc/x86.h | 8 ++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/atomic_ops.h b/src/atomic_ops.h index a37ea71..9e054c2 100644 --- a/src/atomic_ops.h +++ b/src/atomic_ops.h @@ -176,6 +176,13 @@ # define AO_EXPECT_FALSE(expr) (expr) #endif /* !__GNUC__ */ +#if defined(__has_feature) + /* __has_feature() is supported. */ +# if __has_feature(address_sanitizer) +# define AO_ADDRESS_SANITIZER +# endif +#endif + #if defined(__GNUC__) && !defined(__INTEL_COMPILER) # define AO_compiler_barrier() __asm__ __volatile__("" : : : "memory") #elif defined(_MSC_VER) || defined(__DMC__) || defined(__BORLANDC__) \ diff --git a/src/atomic_ops/sysdeps/gcc/x86.h b/src/atomic_ops/sysdeps/gcc/x86.h index 166e353..ded34ac 100644 --- a/src/atomic_ops/sysdeps/gcc/x86.h +++ b/src/atomic_ops/sysdeps/gcc/x86.h @@ -25,11 +25,15 @@ /* TODO: Refine for newer clang releases. */ # if defined(__clang__) \ - && !(defined(__x86_64__) || defined(__APPLE_CC__) \ - || defined(__CYGWIN__) || defined(AO_PREFER_BUILTIN_ATOMICS)) + && (!(defined(__x86_64__) || defined(__APPLE_CC__) \ + || defined(__CYGWIN__) || defined(AO_PREFER_BUILTIN_ATOMICS)) \ + || (defined(AO_ADDRESS_SANITIZER) && defined(__x86_64__) \ + && !defined(__ILP32__))) /* As of clang-3.8 i686 (NDK r11c), it requires -latomic for all */ /* the double-wide operations. For now, we fall back to the */ /* non-intrinsic implementation by default. */ + /* As of clang-3.8, double-wide arguments are incorrectly passed to */ + /* atomic intrinsic operations for x64 target if ASan is enabled. */ # define AO_SKIPATOMIC_double_compare_and_swap_ANY # define AO_SKIPATOMIC_double_load # define AO_SKIPATOMIC_double_load_acquire -- 2.50.1