1 // RUN: %clangxx_dfsan %s -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -O0 -DO0 -o %t && %run %t
2 // RUN: %clangxx_dfsan %s -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -O1 -o %t && %run %t
4 // REQUIRES: x86_64-target-arch
8 #include <sanitizer/dfsan_interface.h>
11 __attribute__((noinline
))
13 make_pair(int *p
, int i
) { return {p
, i
}; }
15 __attribute__((noinline
))
17 copy_pair1(const std::pair
<int *, int> &pair
) {
21 __attribute__((noinline
))
23 copy_pair2(std::pair
<int *, int> *pair
) {
27 __attribute__((noinline
))
29 copy_pair3(std::pair
<int *, int> &&pair
) {
30 return std::move(pair
);
33 __attribute__((noinline
))
34 std::pair
<const char *, uint32_t>
35 return_ptr_and_i32(const char *p
, uint32_t res
) {
36 for (uint32_t i
= 2; i
< 5; i
++) {
37 uint32_t byte
= static_cast<uint8_t>(p
[i
]);
38 res
+= (byte
- 1) << (7 * i
);
40 return {p
+ i
+ 1, res
};
46 __attribute__((noinline
))
47 std::pair
<const char *, uint64_t>
48 return_ptr_and_i64(const char *p
, uint32_t res32
) {
50 for (uint32_t i
= 2; i
< 10; i
++) {
51 uint64_t byte
= static_cast<uint8_t>(p
[i
]);
52 res
+= (byte
- 1) << (7 * i
);
54 return {p
+ i
+ 1, res
};
60 void test_simple_constructors() {
63 dfsan_set_label(8, &i
, sizeof(i
));
64 dfsan_set_label(2, &ptr
, sizeof(ptr
));
66 std::pair
<int *, int> pair1
= make_pair(ptr
, i
);
67 int i1
= pair1
.second
;
68 int *ptr1
= pair1
.first
;
71 assert(dfsan_read_label(&i1
, sizeof(i1
)) == 10);
72 assert(dfsan_read_label(&ptr1
, sizeof(ptr1
)) == 10);
74 assert(dfsan_read_label(&i1
, sizeof(i1
)) == 8);
75 assert(dfsan_read_label(&ptr1
, sizeof(ptr1
)) == 2);
78 std::pair
<int *, int> pair2
= copy_pair1(pair1
);
79 int i2
= pair2
.second
;
80 int *ptr2
= pair2
.first
;
83 assert(dfsan_read_label(&i2
, sizeof(i2
)) == 10);
84 assert(dfsan_read_label(&ptr2
, sizeof(ptr2
)) == 10);
86 assert(dfsan_read_label(&i2
, sizeof(i2
)) == 8);
87 assert(dfsan_read_label(&ptr2
, sizeof(ptr2
)) == 2);
90 std::pair
<int *, int> pair3
= copy_pair2(&pair1
);
91 int i3
= pair3
.second
;
92 int *ptr3
= pair3
.first
;
95 assert(dfsan_read_label(&i3
, sizeof(i3
)) == 10);
96 assert(dfsan_read_label(&ptr3
, sizeof(ptr3
)) == 10);
98 assert(dfsan_read_label(&i3
, sizeof(i3
)) == 8);
99 assert(dfsan_read_label(&ptr3
, sizeof(ptr3
)) == 2);
102 std::pair
<int *, int> pair4
= copy_pair3(std::move(pair1
));
103 int i4
= pair4
.second
;
104 int *ptr4
= pair4
.first
;
107 assert(dfsan_read_label(&i4
, sizeof(i4
)) == 10);
108 assert(dfsan_read_label(&ptr4
, sizeof(ptr4
)) == 10);
110 assert(dfsan_read_label(&i4
, sizeof(i4
)) == 8);
111 assert(dfsan_read_label(&ptr4
, sizeof(ptr4
)) == 2);
115 void test_branches() {
117 dfsan_set_label(8, &res
, sizeof(res
));
121 dfsan_set_label(2, &q
, sizeof(q
));
124 std::fill_n(p
, 100, static_cast<char>(128));
127 std::pair
<const char *, uint32_t> r
= return_ptr_and_i32(q
, res
);
128 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 0);
129 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 0);
133 std::pair
<const char *, uint64_t> r
= return_ptr_and_i64(q
, res
);
134 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 0);
135 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 0);
140 std::fill_n(p
, 100, 0);
143 std::pair
<const char *, uint32_t> r
= return_ptr_and_i32(q
, res
);
145 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 10);
146 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 10);
148 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 2);
149 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 8);
154 std::pair
<const char *, uint64_t> r
= return_ptr_and_i64(q
, res
);
156 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 10);
157 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 10);
159 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 2);
160 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 8);
167 test_simple_constructors();