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