1 | // RUN: %clang_tysan -O0 %s -o %t && %run %t >%t.out.0 2>&1 |
2 | // RUN: FileCheck %s < %t.out.0 |
3 | // RUN: %clang_tysan -O2 %s -o %t && %run %t >%t.out 2>&1 |
4 | // RUN: FileCheck %s < %t.out |
5 | |
6 | #include <stdio.h> |
7 | |
8 | // There's no type-based-aliasing violation here: the memcpy is implemented |
9 | // using only char* or unsigned char* (both of which may alias anything). |
10 | // CHECK-NOT: ERROR: TypeSanitizer: type-aliasing-violation |
11 | |
12 | void my_memcpy_uchar(void *dest, void *src, int n) { |
13 | unsigned char *p = dest, *q = src, *end = p + n; |
14 | while (p < end) |
15 | *p++ = *q++; |
16 | } |
17 | |
18 | void my_memcpy_char(void *dest, void *src, int n) { |
19 | char *p = dest, *q = src, *end = p + n; |
20 | while (p < end) |
21 | *p++ = *q++; |
22 | } |
23 | |
24 | void test_uchar() { |
25 | struct S { |
26 | short x; |
27 | short *r; |
28 | } s = {10, &s.x}, s2; |
29 | my_memcpy_uchar(dest: &s2, src: &s, n: sizeof(struct S)); |
30 | printf(format: "%d\n" , *(s2.r)); |
31 | } |
32 | |
33 | void test_char() { |
34 | struct S { |
35 | short x; |
36 | short *r; |
37 | } s = {10, &s.x}, s2; |
38 | my_memcpy_char(dest: &s2, src: &s, n: sizeof(struct S)); |
39 | printf(format: "%d\n" , *(s2.r)); |
40 | } |
41 | |
42 | int main() { |
43 | test_uchar(); |
44 | test_char(); |
45 | } |
46 | |