Index: lib/asan/asan_fake_stack.cc =================================================================== --- lib/asan/asan_fake_stack.cc +++ lib/asan/asan_fake_stack.cc @@ -27,8 +27,10 @@ CHECK_EQ(SHADOW_SCALE, 3); // This code expects SHADOW_SCALE=3. u64 *shadow = reinterpret_cast(MemToShadow(ptr)); if (class_id <= 6) { - for (uptr i = 0; i < (1U << class_id); i++) + for (uptr i = 0; i < (1U << class_id); i++) { shadow[i] = magic; + break_optimization(0); // Make sure this does not become memset. + } } else { // The size class is too big, it's cheaper to poison only size bytes. PoisonShadow(ptr, size, static_cast(magic)); Index: lib/sanitizer_common/sanitizer_common.h =================================================================== --- lib/sanitizer_common/sanitizer_common.h +++ lib/sanitizer_common/sanitizer_common.h @@ -552,6 +552,20 @@ INLINE void GetExtraActivationFlags(char *buf, uptr size) { *buf = '\0'; } INLINE void SanitizerInitializeUnwinder() {} #endif + +// Make the compiler think that something is going on there. +// Use this inside a loop that looks like memset/memcpy/etc to prevent the +// compiler from recognising it and turning it into an actual call to +// memset/memcpy/etc. +static inline void break_optimization(void *arg) { +#if _MSC_VER + // FIXME: make sure this is actually enough. + __asm; +#else + __asm__ __volatile__("" : : "r" (arg) : "memory"); +#endif +} + } // namespace __sanitizer inline void *operator new(__sanitizer::operator_new_size_type size, Index: lib/sanitizer_common/sanitizer_libc.cc =================================================================== --- lib/sanitizer_common/sanitizer_libc.cc +++ lib/sanitizer_common/sanitizer_libc.cc @@ -16,16 +16,6 @@ namespace __sanitizer { -// Make the compiler think that something is going on there. -static inline void break_optimization(void *arg) { -#if _MSC_VER - // FIXME: make sure this is actually enough. - __asm; -#else - __asm__ __volatile__("" : : "r" (arg) : "memory"); -#endif -} - s64 internal_atoll(const char *nptr) { return internal_simple_strtoll(nptr, (char**)0, 10); } Index: lib/sanitizer_common/tests/sanitizer_test_utils.h =================================================================== --- lib/sanitizer_common/tests/sanitizer_test_utils.h +++ lib/sanitizer_common/tests/sanitizer_test_utils.h @@ -64,13 +64,6 @@ # define SANITIZER_WORDSIZE 32 #endif -// Make the compiler thinks that something is going on there. -inline void break_optimization(void *arg) { -#if !defined(_WIN32) || defined(__clang__) - __asm__ __volatile__("" : : "r" (arg) : "memory"); -#endif -} - // This function returns its parameter but in such a way that compiler // can not prove it. template