1 // RUN: %clangxx_asan -O2 -fsanitize-address-outline-instrumentation %s -o %t
2 // RUN: not %run %t A 2>&1 | FileCheck %s --check-prefix=CHECK_0_BYTES
3 // RUN: not %run %t B 2>&1 | FileCheck %s --check-prefix=CHECK_0_BYTES
4 // RUN: not %run %t C 2>&1 | FileCheck %s --check-prefix=CHECK_1_BYTES
5 // RUN: not %run %t D 2>&1 | FileCheck %s --check-prefix=CHECK_1_BYTES
6
7 // RUN: %clangxx_asan -O2 -fsanitize-address-outline-instrumentation %s -o %t \
8 // RUN: -mllvm -asan-recover=1
9 // RUN: not %run %t A 2>&1 | FileCheck %s --check-prefix=CHECK_0_BYTES
10 // RUN: not %run %t B 2>&1 | FileCheck %s --check-prefix=CHECK_0_BYTES
11 // RUN: not %run %t C 2>&1 | FileCheck %s --check-prefix=CHECK_1_BYTES
12 // RUN: not %run %t D 2>&1 | FileCheck %s --check-prefix=CHECK_1_BYTES
13
14 // RUN: %clangxx_asan -O2 -fsanitize-address-outline-instrumentation %s -o %t \
15 // RUN: -mllvm -asan-force-experiment=42
16 // RUN: not %run %t A 2>&1 | FileCheck %s --check-prefix=CHECK_0_BYTES
17 // RUN: not %run %t B 2>&1 | FileCheck %s --check-prefix=CHECK_0_BYTES
18 // RUN: not %run %t C 2>&1 | FileCheck %s --check-prefix=CHECK_1_BYTES
19 // RUN: not %run %t D 2>&1 | FileCheck %s --check-prefix=CHECK_1_BYTES
20
21 // CHECK_0_BYTES: ERROR: AddressSanitizer: global-buffer-overflow on address [[ADDR:.*]] at
22 // CHECK_0_BYTES: [[ADDR]] is located 0 bytes after
23
24 // CHECK_1_BYTES: ERROR: AddressSanitizer: global-buffer-overflow on address [[ADDR:.*]] at
25 // CHECK_1_BYTES: [[ADDR]] is located 1 bytes after
26
27 #include <sanitizer/asan_interface.h>
28
29 #include <stdlib.h>
30 #include <string.h>
31
32 static int64_t mem = -1;
33 static int64_t *volatile G = &mem;
34
UNALIGNED_LOAD(const void * p)35 inline uint16_t UNALIGNED_LOAD(const void *p) {
36 uint16_t data;
37 memcpy(&data, p, sizeof data);
38 return data;
39 }
40
UNALIGNED_STORE(uint16_t data,void * p)41 inline void UNALIGNED_STORE(uint16_t data, void *p) {
42 memcpy(p, &data, sizeof data);
43 }
44
main(int argc,char ** argv)45 int main(int argc, char **argv) {
46 if (argc != 2)
47 return 1;
48 int res = 1;
49 switch (argv[1][0]) {
50 case 'A':
51 res = UNALIGNED_LOAD(reinterpret_cast<char *>(G) + 7);
52 break;
53 case 'B':
54 UNALIGNED_STORE(0, reinterpret_cast<char *>(G) + 7);
55 break;
56 case 'C':
57 res = UNALIGNED_LOAD(reinterpret_cast<char *>(G) + 9);
58 break;
59 case 'D':
60 UNALIGNED_STORE(0, reinterpret_cast<char *>(G) + 9);
61 break;
62 }
63 return res;
64 }
65