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; + SanitizerBreakOptimization(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 @@ -535,6 +535,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 SanitizerBreakOptimization(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); } @@ -78,7 +68,7 @@ CHECK_EQ((reinterpret_cast(s) | n) & 15, 0); for (S16 *p = reinterpret_cast(s), *end = p + n / 16; p < end; p++) { p->a = p->b = 0; - break_optimization(0); // Make sure this does not become memset. + SanitizerBreakOptimization(0); // Make sure this does not become memset. } }