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
9struct 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(addr: _data._s._ch, size: 23);
28 }
29
30 ~S() {
31 __asan_unpoison_memory_region(addr: _data._s._ch, size: 23);
32 }
33
34 bool is_long() const {
35 return _data._s._size & 1;
36 }
37
38 const char* get_pointer() const {
39 return is_long() ? _data._l._ptr : _data._s._ch;
40 }
41};
42
43
44inline void side_effect(const void *arg) {
45 __asm__ __volatile__("" : : "r" (arg) : "memory");
46}
47
48int main(int argc, char **argv) {
49 S s;
50 side_effect(arg: &s); // optimizer is too smart otherwise
51 const char *ptr = s.get_pointer();
52 side_effect(arg: ptr); // force use ptr
53 return 0;
54}
55

source code of compiler-rt/test/asan/TestCases/speculative_load.cpp