xref: /llvm-project/compiler-rt/test/asan/TestCases/speculative_load.cpp (revision 673dc3d4a0b0fbb3b9b34ae2ecbfa522627fe582)
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 Weber inline 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 Weber int 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