58 lines · cpp
1// Verifies that speculative loads from unions do not happen under asan.2// RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&13// RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&14// RUN: %clangxx_asan -O2 %s -o %t && %run %t 2>&15// RUN: %clangxx_asan -O3 %s -o %t && %run %t 2>&16 7// MSVC doesn't support GCC style inline assembly8// UNSUPPORTED: msvc9 10#include <sanitizer/asan_interface.h>11 12struct S {13 struct _long {14 void* _pad;15 const char* _ptr;16 };17 18 struct _short {19 unsigned char _size;20 char _ch[23];21 };22 23 union {24 _short _s;25 _long _l;26 } _data;27 28 S() {29 _data._s._size = 0;30 __asan_poison_memory_region(_data._s._ch, 23);31 }32 33 ~S() {34 __asan_unpoison_memory_region(_data._s._ch, 23);35 }36 37 bool is_long() const {38 return _data._s._size & 1;39 }40 41 const char* get_pointer() const {42 return is_long() ? _data._l._ptr : _data._s._ch;43 }44};45 46 47inline void side_effect(const void *arg) {48 __asm__ __volatile__("" : : "r" (arg) : "memory");49}50 51int main(int argc, char **argv) {52 S s;53 side_effect(&s); // optimizer is too smart otherwise54 const char *ptr = s.get_pointer();55 side_effect(ptr); // force use ptr56 return 0;57}58