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