• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
is_longS30   bool is_long() const {
31     return _data._s._size & 1;
32   }
33 
get_pointerS34   const char* get_pointer() const {
35     return is_long() ? _data._l._ptr : _data._s._ch;
36   }
37 };
38 
39 
side_effect(const void * arg)40 inline void side_effect(const void *arg) {
41   __asm__ __volatile__("" : : "r" (arg) : "memory");
42 }
43 
main(int argc,char ** argv)44 int main(int argc, char **argv) {
45   S s;
46   side_effect(&s); // optimizer is too smart otherwise
47   const char *ptr = s.get_pointer();
48   side_effect(ptr); // force use ptr
49   return 0;
50 }
51