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 -O0 -DO0 -o %t && %run %t 2 // RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -O1 -o %t && %run %t 3 4 #include <algorithm> 5 #include <assert.h> 6 #include <sanitizer/dfsan_interface.h> 7 #include <utility> 8 9 __attribute__((noinline)) 10 std::pair<int *, int> 11 make_pair(int *p, int i) { return {p, i}; } 12 13 __attribute__((noinline)) 14 std::pair<int *, int> 15 copy_pair1(const std::pair<int *, int> &pair) { 16 return pair; 17 } 18 19 __attribute__((noinline)) 20 std::pair<int *, int> 21 copy_pair2(std::pair<int *, int> *pair) { 22 return *pair; 23 } 24 25 __attribute__((noinline)) 26 std::pair<int *, int> 27 copy_pair3(std::pair<int *, int> &&pair) { 28 return std::move(pair); 29 } 30 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); 37 if (byte < 128) { 38 return {p + i + 1, res}; 39 } 40 } 41 return {nullptr, 0}; 42 } 43 44 __attribute__((noinline)) 45 std::pair<const char *, uint64_t> 46 return_ptr_and_i64(const char *p, uint32_t res32) { 47 uint64_t res = 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); 51 if (byte < 128) { 52 return {p + i + 1, res}; 53 } 54 } 55 return {nullptr, 0}; 56 } 57 58 void test_simple_constructors() { 59 int i = 1; 60 int *ptr = NULL; 61 dfsan_set_label(8, &i, sizeof(i)); 62 dfsan_set_label(2, &ptr, sizeof(ptr)); 63 64 std::pair<int *, int> pair1 = make_pair(ptr, i); 65 int i1 = pair1.second; 66 int *ptr1 = pair1.first; 67 68 #ifdef O0 69 assert(dfsan_read_label(&i1, sizeof(i1)) == 10); 70 assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 10); 71 #else 72 assert(dfsan_read_label(&i1, sizeof(i1)) == 8); 73 assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 2); 74 #endif 75 76 std::pair<int *, int> pair2 = copy_pair1(pair1); 77 int i2 = pair2.second; 78 int *ptr2 = pair2.first; 79 80 #ifdef O0 81 assert(dfsan_read_label(&i2, sizeof(i2)) == 10); 82 assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 10); 83 #else 84 assert(dfsan_read_label(&i2, sizeof(i2)) == 8); 85 assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 2); 86 #endif 87 88 std::pair<int *, int> pair3 = copy_pair2(&pair1); 89 int i3 = pair3.second; 90 int *ptr3 = pair3.first; 91 92 #ifdef O0 93 assert(dfsan_read_label(&i3, sizeof(i3)) == 10); 94 assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 10); 95 #else 96 assert(dfsan_read_label(&i3, sizeof(i3)) == 8); 97 assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 2); 98 #endif 99 100 std::pair<int *, int> pair4 = copy_pair3(std::move(pair1)); 101 int i4 = pair4.second; 102 int *ptr4 = pair4.first; 103 104 #ifdef O0 105 assert(dfsan_read_label(&i4, sizeof(i4)) == 10); 106 assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 10); 107 #else 108 assert(dfsan_read_label(&i4, sizeof(i4)) == 8); 109 assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 2); 110 #endif 111 } 112 113 void test_branches() { 114 uint32_t res = 4; 115 dfsan_set_label(8, &res, sizeof(res)); 116 117 char p[100]; 118 const char *q = p; 119 dfsan_set_label(2, &q, sizeof(q)); 120 121 { 122 std::fill_n(p, 100, static_cast<char>(128)); 123 124 { 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); 128 } 129 130 { 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); 134 } 135 } 136 137 { 138 std::fill_n(p, 100, 0); 139 140 { 141 std::pair<const char *, uint32_t> r = return_ptr_and_i32(q, res); 142 #ifdef O0 143 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10); 144 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10); 145 #else 146 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 2); 147 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 8); 148 #endif 149 } 150 151 { 152 std::pair<const char *, uint64_t> r = return_ptr_and_i64(q, res); 153 #ifdef O0 154 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10); 155 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10); 156 #else 157 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 2); 158 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 8); 159 #endif 160 } 161 } 162 } 163 164 int main(void) { 165 test_simple_constructors(); 166 test_branches(); 167 168 return 0; 169 } 170