Home | History | Annotate | Download | only in TestCases
      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 
     25   S() {
     26     _data._s._size = 0;
     27     __asan_poison_memory_region(_data._s._ch, 23);
     28   }
     29 
     30   bool is_long() const {
     31     return _data._s._size & 1;
     32   }
     33 
     34   const char* get_pointer() const {
     35     return is_long() ? _data._l._ptr : _data._s._ch;
     36   }
     37 };
     38 
     39 
     40 inline void side_effect(const void *arg) {
     41   __asm__ __volatile__("" : : "r" (arg) : "memory");
     42 }
     43 
     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