170 lines · cpp
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 %t2// RUN: %clangxx_dfsan %s -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -O1 -o %t && %run %t3 4#include <algorithm>5#include <assert.h>6#include <sanitizer/dfsan_interface.h>7#include <utility>8 9__attribute__((noinline))10std::pair<int *, int>11make_pair(int *p, int i) { return {p, i}; }12 13__attribute__((noinline))14std::pair<int *, int>15copy_pair1(const std::pair<int *, int> &pair) {16 return pair;17}18 19__attribute__((noinline))20std::pair<int *, int>21copy_pair2(std::pair<int *, int> *pair) {22 return *pair;23}24 25__attribute__((noinline))26std::pair<int *, int>27copy_pair3(std::pair<int *, int> &&pair) {28 return std::move(pair);29}30 31__attribute__((noinline))32std::pair<const char *, uint32_t>33return_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))45std::pair<const char *, uint64_t>46return_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 58void 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 O069 assert(dfsan_read_label(&i1, sizeof(i1)) == 10);70 assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 10);71#else72 assert(dfsan_read_label(&i1, sizeof(i1)) == 8);73 assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 2);74#endif75 76 std::pair<int *, int> pair2 = copy_pair1(pair1);77 int i2 = pair2.second;78 int *ptr2 = pair2.first;79 80#ifdef O081 assert(dfsan_read_label(&i2, sizeof(i2)) == 10);82 assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 10);83#else84 assert(dfsan_read_label(&i2, sizeof(i2)) == 8);85 assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 2);86#endif87 88 std::pair<int *, int> pair3 = copy_pair2(&pair1);89 int i3 = pair3.second;90 int *ptr3 = pair3.first;91 92#ifdef O093 assert(dfsan_read_label(&i3, sizeof(i3)) == 10);94 assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 10);95#else96 assert(dfsan_read_label(&i3, sizeof(i3)) == 8);97 assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 2);98#endif99 100 std::pair<int *, int> pair4 = copy_pair3(std::move(pair1));101 int i4 = pair4.second;102 int *ptr4 = pair4.first;103 104#ifdef O0105 assert(dfsan_read_label(&i4, sizeof(i4)) == 10);106 assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 10);107#else108 assert(dfsan_read_label(&i4, sizeof(i4)) == 8);109 assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 2);110#endif111}112 113void 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 O0143 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10);144 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10);145#else146 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 2);147 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 8);148#endif149 }150 151 {152 std::pair<const char *, uint64_t> r = return_ptr_and_i64(q, res);153#ifdef O0154 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10);155 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10);156#else157 assert(dfsan_read_label(&r.first, sizeof(r.first)) == 2);158 assert(dfsan_read_label(&r.second, sizeof(r.second)) == 8);159#endif160 }161 }162}163 164int main(void) {165 test_simple_constructors();166 test_branches();167 168 return 0;169}170