1*673dc3d4SNico Weber // Verifies that speculative loads from unions do not happen under asan. 2*673dc3d4SNico Weber // RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&1 3*673dc3d4SNico Weber // RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&1 4*673dc3d4SNico Weber // RUN: %clangxx_asan -O2 %s -o %t && %run %t 2>&1 5*673dc3d4SNico Weber // RUN: %clangxx_asan -O3 %s -o %t && %run %t 2>&1 6*673dc3d4SNico Weber 7*673dc3d4SNico Weber #include <sanitizer/asan_interface.h> 8*673dc3d4SNico Weber 9*673dc3d4SNico Weber struct S { 10*673dc3d4SNico Weber struct _long { 11*673dc3d4SNico Weber void* _pad; 12*673dc3d4SNico Weber const char* _ptr; 13*673dc3d4SNico Weber }; 14*673dc3d4SNico Weber 15*673dc3d4SNico Weber struct _short { 16*673dc3d4SNico Weber unsigned char _size; 17*673dc3d4SNico Weber char _ch[23]; 18*673dc3d4SNico Weber }; 19*673dc3d4SNico Weber 20*673dc3d4SNico Weber union { 21*673dc3d4SNico Weber _short _s; 22*673dc3d4SNico Weber _long _l; 23*673dc3d4SNico Weber } _data; 24*673dc3d4SNico Weber SS25*673dc3d4SNico Weber S() { 26*673dc3d4SNico Weber _data._s._size = 0; 27*673dc3d4SNico Weber __asan_poison_memory_region(_data._s._ch, 23); 28*673dc3d4SNico Weber } 29*673dc3d4SNico Weber ~SS30*673dc3d4SNico Weber ~S() { 31*673dc3d4SNico Weber __asan_unpoison_memory_region(_data._s._ch, 23); 32*673dc3d4SNico Weber } 33*673dc3d4SNico Weber is_longS34*673dc3d4SNico Weber bool is_long() const { 35*673dc3d4SNico Weber return _data._s._size & 1; 36*673dc3d4SNico Weber } 37*673dc3d4SNico Weber get_pointerS38*673dc3d4SNico Weber const char* get_pointer() const { 39*673dc3d4SNico Weber return is_long() ? _data._l._ptr : _data._s._ch; 40*673dc3d4SNico Weber } 41*673dc3d4SNico Weber }; 42*673dc3d4SNico Weber 43*673dc3d4SNico Weber side_effect(const void * arg)44*673dc3d4SNico Weberinline void side_effect(const void *arg) { 45*673dc3d4SNico Weber __asm__ __volatile__("" : : "r" (arg) : "memory"); 46*673dc3d4SNico Weber } 47*673dc3d4SNico Weber main(int argc,char ** argv)48*673dc3d4SNico Weberint main(int argc, char **argv) { 49*673dc3d4SNico Weber S s; 50*673dc3d4SNico Weber side_effect(&s); // optimizer is too smart otherwise 51*673dc3d4SNico Weber const char *ptr = s.get_pointer(); 52*673dc3d4SNico Weber side_effect(ptr); // force use ptr 53*673dc3d4SNico Weber return 0; 54*673dc3d4SNico Weber } 55