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
6 #include <sanitizer/dfsan_interface.h>
9 __attribute__((noinline
))
11 make_pair(int *p
, int i
) { return {p
, i
}; }
13 __attribute__((noinline
))
15 copy_pair1(const std::pair
<int *, int> &pair
) {
19 __attribute__((noinline
))
21 copy_pair2(std::pair
<int *, int> *pair
) {
25 __attribute__((noinline
))
27 copy_pair3(std::pair
<int *, int> &&pair
) {
28 return std::move(pair
);
31 __attribute__((noinline
))
32 std::pair
<const char *, uint32_t>
33 return_ptr_and_i32(const char *p
, uint32_t res
) {
34 for (uint32_t i
= 2; i
< 5; i
++) {
35 uint32_t byte
= static_cast<uint8_t>(p
[i
]);
36 res
+= (byte
- 1) << (7 * i
);
38 return {p
+ i
+ 1, res
};
44 __attribute__((noinline
))
45 std::pair
<const char *, uint64_t>
46 return_ptr_and_i64(const char *p
, uint32_t res32
) {
48 for (uint32_t i
= 2; i
< 10; i
++) {
49 uint64_t byte
= static_cast<uint8_t>(p
[i
]);
50 res
+= (byte
- 1) << (7 * i
);
52 return {p
+ i
+ 1, res
};
58 void test_simple_constructors() {
61 dfsan_set_label(8, &i
, sizeof(i
));
62 dfsan_set_label(2, &ptr
, sizeof(ptr
));
64 std::pair
<int *, int> pair1
= make_pair(ptr
, i
);
65 int i1
= pair1
.second
;
66 int *ptr1
= pair1
.first
;
69 assert(dfsan_read_label(&i1
, sizeof(i1
)) == 10);
70 assert(dfsan_read_label(&ptr1
, sizeof(ptr1
)) == 10);
72 assert(dfsan_read_label(&i1
, sizeof(i1
)) == 8);
73 assert(dfsan_read_label(&ptr1
, sizeof(ptr1
)) == 2);
76 std::pair
<int *, int> pair2
= copy_pair1(pair1
);
77 int i2
= pair2
.second
;
78 int *ptr2
= pair2
.first
;
81 assert(dfsan_read_label(&i2
, sizeof(i2
)) == 10);
82 assert(dfsan_read_label(&ptr2
, sizeof(ptr2
)) == 10);
84 assert(dfsan_read_label(&i2
, sizeof(i2
)) == 8);
85 assert(dfsan_read_label(&ptr2
, sizeof(ptr2
)) == 2);
88 std::pair
<int *, int> pair3
= copy_pair2(&pair1
);
89 int i3
= pair3
.second
;
90 int *ptr3
= pair3
.first
;
93 assert(dfsan_read_label(&i3
, sizeof(i3
)) == 10);
94 assert(dfsan_read_label(&ptr3
, sizeof(ptr3
)) == 10);
96 assert(dfsan_read_label(&i3
, sizeof(i3
)) == 8);
97 assert(dfsan_read_label(&ptr3
, sizeof(ptr3
)) == 2);
100 std::pair
<int *, int> pair4
= copy_pair3(std::move(pair1
));
101 int i4
= pair4
.second
;
102 int *ptr4
= pair4
.first
;
105 assert(dfsan_read_label(&i4
, sizeof(i4
)) == 10);
106 assert(dfsan_read_label(&ptr4
, sizeof(ptr4
)) == 10);
108 assert(dfsan_read_label(&i4
, sizeof(i4
)) == 8);
109 assert(dfsan_read_label(&ptr4
, sizeof(ptr4
)) == 2);
113 void test_branches() {
115 dfsan_set_label(8, &res
, sizeof(res
));
119 dfsan_set_label(2, &q
, sizeof(q
));
122 std::fill_n(p
, 100, static_cast<char>(128));
125 std::pair
<const char *, uint32_t> r
= return_ptr_and_i32(q
, res
);
126 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 0);
127 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 0);
131 std::pair
<const char *, uint64_t> r
= return_ptr_and_i64(q
, res
);
132 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 0);
133 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 0);
138 std::fill_n(p
, 100, 0);
141 std::pair
<const char *, uint32_t> r
= return_ptr_and_i32(q
, res
);
143 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 10);
144 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 10);
146 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 2);
147 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 8);
152 std::pair
<const char *, uint64_t> r
= return_ptr_and_i64(q
, res
);
154 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 10);
155 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 10);
157 assert(dfsan_read_label(&r
.first
, sizeof(r
.first
)) == 2);
158 assert(dfsan_read_label(&r
.second
, sizeof(r
.second
)) == 8);
165 test_simple_constructors();