1// RUN: %clang_dfsan %s -O1 -mllvm -dfsan-fast-16-labels=true -DFAST16_O1 -o %t && %run %t
2// RUN: %clang_dfsan %s -O1 -DO1 -o %t && %run %t
3// RUN: %clang_dfsan %s -O0 -mllvm -dfsan-fast-16-labels=true -DFAST16_O0 -o %t && %run %t
4// RUN: %clang_dfsan %s -O0 -DO0 -o %t && %run %t
5//
6// REQUIRES: x86_64-target-arch
7
8#include <assert.h>
9#include <sanitizer/dfsan_interface.h>
10
11typedef struct Pair {
12 int i;
13 char *ptr;
14} Pair;
15
16__attribute__((noinline))
17Pair make_pair(int i, char *ptr) {
18 Pair pair;
19 pair.i = i;
20 pair.ptr = ptr;
21 return pair;
22}
23
24__attribute__((noinline))
25Pair copy_pair1(const Pair *pair0) {
26 Pair pair;
27 pair.i = pair0->i;
28 pair.ptr = pair0->ptr;
29 return pair;
30}
31
32__attribute__((noinline))
33Pair copy_pair2(const Pair pair0) {
34 Pair pair;
35 pair.i = pair0.i;
36 pair.ptr = pair0.ptr;
37 return pair;
38}
39
40int main(void) {
41 int i = 1;
42 char *ptr = NULL;
43#if defined(FAST16_O1) || defined(FAST16_O0)
44 dfsan_label i_label = 1;
45 dfsan_label ptr_label = 2;
46#else
47 dfsan_label i_label = dfsan_create_label("i", 0);
48 dfsan_label ptr_label = dfsan_create_label("ptr", 0);
49#endif
50 dfsan_set_label(i_label, &i, sizeof(i));
51 dfsan_set_label(ptr_label, &ptr, sizeof(ptr));
52
53 Pair pair1 = make_pair(i, ptr);
54 int i1 = pair1.i;
55 char *ptr1 = pair1.ptr;
56
57 dfsan_label i1_label = dfsan_read_label(&i1, sizeof(i1));
58 dfsan_label ptr1_label = dfsan_read_label(&ptr1, sizeof(ptr1));
59#if defined(O0) || defined(O1)
60 assert(dfsan_has_label(i1_label, i_label));
61 assert(dfsan_has_label(i1_label, ptr_label));
62 assert(dfsan_has_label(ptr1_label, i_label));
63 assert(dfsan_has_label(ptr1_label, ptr_label));
64#elif defined(FAST16_O0)
65 assert(i1_label == (i_label | ptr_label));
66 assert(ptr1_label == (i_label | ptr_label));
67#else
68 assert(i1_label == i_label);
69 assert(ptr1_label == ptr_label);
70#endif
71
72 Pair pair2 = copy_pair1(&pair1);
73 int i2 = pair2.i;
74 char *ptr2 = pair2.ptr;
75
76 dfsan_label i2_label = dfsan_read_label(&i2, sizeof(i2));
77 dfsan_label ptr2_label = dfsan_read_label(&ptr2, sizeof(ptr2));
78#if defined(O0) || defined(O1)
79 assert(dfsan_has_label(i2_label, i_label));
80 assert(dfsan_has_label(i2_label, ptr_label));
81 assert(dfsan_has_label(ptr2_label, i_label));
82 assert(dfsan_has_label(ptr2_label, ptr_label));
83#elif defined(FAST16_O0)
84 assert(i2_label == (i_label | ptr_label));
85 assert(ptr2_label == (i_label | ptr_label));
86#else
87 assert(i2_label == i_label);
88 assert(ptr2_label == ptr_label);
89#endif
90
91 Pair pair3 = copy_pair2(pair1);
92 int i3 = pair3.i;
93 char *ptr3 = pair3.ptr;
94
95 dfsan_label i3_label = dfsan_read_label(&i3, sizeof(i3));
96 dfsan_label ptr3_label = dfsan_read_label(&ptr3, sizeof(ptr3));
97#if defined(O0) || defined(O1)
98 assert(dfsan_has_label(i3_label, i_label));
99 assert(dfsan_has_label(i3_label, ptr_label));
100 assert(dfsan_has_label(ptr3_label, i_label));
101 assert(dfsan_has_label(ptr3_label, ptr_label));
102#elif defined(FAST16_O0)
103 assert(i3_label == (i_label | ptr_label));
104 assert(ptr3_label == (i_label | ptr_label));
105#else
106 assert(i3_label == i_label);
107 assert(ptr3_label == ptr_label);
108#endif
109
110
111 return 0;
112}
113