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 | |
35 | inline uint16_t UNALIGNED_LOAD(const void *p) { |
36 | uint16_t data; |
37 | memcpy(dest: &data, src: p, n: sizeof data); |
38 | return data; |
39 | } |
40 | |
41 | inline void UNALIGNED_STORE(uint16_t data, void *p) { |
42 | memcpy(dest: p, src: &data, n: sizeof data); |
43 | } |
44 | |
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(p: reinterpret_cast<char *>(G) + 7); |
52 | break; |
53 | case 'B': |
54 | UNALIGNED_STORE(data: 0, p: reinterpret_cast<char *>(G) + 7); |
55 | break; |
56 | case 'C': |
57 | res = UNALIGNED_LOAD(p: reinterpret_cast<char *>(G) + 9); |
58 | break; |
59 | case 'D': |
60 | UNALIGNED_STORE(data: 0, p: reinterpret_cast<char *>(G) + 9); |
61 | break; |
62 | } |
63 | return res; |
64 | } |
65 | |