1 // RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -o %t && %run %t 2 3 #include <algorithm> 4 #include <assert.h> 5 #include <sanitizer/dfsan_interface.h> 6 #include <utility> 7 8 __attribute__((noinline)) 9 std::pair<int *, int> 10 make_pair(int *p, int i) { return {p, i}; } 11 12 __attribute__((noinline)) 13 std::pair<int *, int> 14 copy_pair1(const std::pair<int *, int> &pair) { 15 return pair; 16 } 17 18 __attribute__((noinline)) 19 std::pair<int *, int> 20 copy_pair2(std::pair<int *, int> *pair) { 21 return *pair; 22 } 23 24 __attribute__((noinline)) 25 std::pair<int *, int> 26 copy_pair3(std::pair<int *, int> &&pair) { 27 return std::move(pair); 28 } 29 30 __attribute__((noinline)) 31 std::pair<const char *, uint32_t> 32 return_ptr_and_i32(const char *p, uint32_t res) { 33 for (uint32_t i = 2; i < 5; i++) { 34 uint32_t byte = static_cast<uint8_t>(p[i]); 35 res += (byte - 1) << (7 * i); 36 if (byte < 128) { 37 return {p + i + 1, res}; 38 } 39 } 40 return {nullptr, 0}; 41 } 42 43 __attribute__((noinline)) 44 std::pair<const char *, uint64_t> 45 return_ptr_and_i64(const char *p, uint32_t res32) { 46 uint64_t res = res32; 47 for (uint32_t i = 2; i < 10; i++) { 48 uint64_t byte = static_cast<uint8_t>(p[i]); 49 res += (byte - 1) << (7 * i); 50 if (byte < 128) { 51 return {p + i + 1, res}; 52 } 53 } 54 return {nullptr, 0}; 55 } 56 57 void test_simple_constructors() { 58 int i = 1; 59 int *ptr = NULL; 60 dfsan_set_label(8, &i, sizeof(i)); 61 dfsan_set_label(2, &ptr, sizeof(ptr)); 62 63 std::pair<int *, int> pair1 = make_pair(ptr, i); 64 int i1 = pair1.second; 65 int *ptr1 = pair1.first; 66 67 assert(dfsan_read_label(&i1, sizeof(i1)) == 10); 68 assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 10); 69 70 std::pair<int *, int> pair2 = copy_pair1(pair1); 71 int i2 = pair2.second; 72 int *ptr2 = pair2.first; 73 74 assert(dfsan_read_label(&i2, sizeof(i2)) == 10); 75 assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 10); 76 77 std::pair<int *, int> pair3 = copy_pair2(&pair1); 78 int i3 = pair3.second; 79 int *ptr3 = pair3.first; 80 81 assert(dfsan_read_label(&i3, sizeof(i3)) == 10); 82 assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 10); 83 84 std::pair<int *, int> pair4 = copy_pair3(std::move(pair1)); 85 int i4 = pair4.second; 86 int *ptr4 = pair4.first; 87 88 assert(dfsan_read_label(&i4, sizeof(i4)) == 10); 89 assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 10); 90 } 91 92 void test_branches() { 93 uint32_t res = 4; 94 dfsan_set_label(8, &res, sizeof(res)); 95 96 char p[100]; 97 const char *q = p; 98 dfsan_set_label(2, &q, sizeof(q)); 99 100 { 101 std::fill_n(p, 100, static_cast<char>(128)); 102 103 { 104 std::pair<const char *, uint32_t> r = return_ptr_and_i32(q, res); 105 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0); 106 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0); 107 } 108 109 { 110 std::pair<const char *, uint64_t> r = return_ptr_and_i64(q, res); 111 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0); 112 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0); 113 } 114 } 115 116 { 117 std::fill_n(p, 100, 0); 118 119 { 120 std::pair<const char *, uint32_t> r = return_ptr_and_i32(q, res); 121 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10); 122 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10); 123 } 124 125 { 126 std::pair<const char *, uint64_t> r = return_ptr_and_i64(q, res); 127 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10); 128 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10); 129 } 130 } 131 } 132 133 int main(void) { 134 test_simple_constructors(); 135 test_branches(); 136 137 return 0; 138 } 139