diff --git a/compiler-rt/test/dfsan/pair.cpp b/compiler-rt/test/dfsan/pair.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/dfsan/pair.cpp @@ -0,0 +1,138 @@ +// 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 + +#include +#include +#include +#include + +__attribute__((noinline)) +std::pair +make_pair(int *p, int i) { return {p, i}; } + +__attribute__((noinline)) +std::pair +copy_pair1(const std::pair &pair) { + return pair; +} + +__attribute__((noinline)) +std::pair +copy_pair2(std::pair *pair) { + return *pair; +} + +__attribute__((noinline)) +std::pair +copy_pair3(std::pair &&pair) { + return std::move(pair); +} + +__attribute__((noinline)) +std::pair +return_ptr_and_i32(const char *p, uint32_t res) { + for (uint32_t i = 2; i < 5; i++) { + uint32_t byte = static_cast(p[i]); + res += (byte - 1) << (7 * i); + if (byte < 128) { + return {p + i + 1, res}; + } + } + return {nullptr, 0}; +} + +__attribute__((noinline)) +std::pair +return_ptr_and_i64(const char *p, uint32_t res32) { + uint64_t res = res32; + for (uint32_t i = 2; i < 10; i++) { + uint64_t byte = static_cast(p[i]); + res += (byte - 1) << (7 * i); + if (byte < 128) { + return {p + i + 1, res}; + } + } + return {nullptr, 0}; +} + +void test_simple_constructors() { + int i = 1; + int *ptr = NULL; + dfsan_set_label(8, &i, sizeof(i)); + dfsan_set_label(2, &ptr, sizeof(ptr)); + + std::pair pair1 = make_pair(ptr, i); + int i1 = pair1.second; + int *ptr1 = pair1.first; + + assert(dfsan_read_label(&i1, sizeof(i1)) == 10); + assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 10); + + std::pair pair2 = copy_pair1(pair1); + int i2 = pair2.second; + int *ptr2 = pair2.first; + + assert(dfsan_read_label(&i2, sizeof(i2)) == 10); + assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 10); + + std::pair pair3 = copy_pair2(&pair1); + int i3 = pair3.second; + int *ptr3 = pair3.first; + + assert(dfsan_read_label(&i3, sizeof(i3)) == 10); + assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 10); + + std::pair pair4 = copy_pair3(std::move(pair1)); + int i4 = pair4.second; + int *ptr4 = pair4.first; + + assert(dfsan_read_label(&i4, sizeof(i4)) == 10); + assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 10); +} + +void test_branches() { + uint32_t res = 4; + dfsan_set_label(8, &res, sizeof(res)); + + char p[100]; + const char *q = p; + dfsan_set_label(2, &q, sizeof(q)); + + { + std::fill_n(p, 100, static_cast(128)); + + { + std::pair r = return_ptr_and_i32(q, res); + assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0); + assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0); + } + + { + std::pair r = return_ptr_and_i64(q, res); + assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0); + assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0); + } + } + + { + std::fill_n(p, 100, 0); + + { + std::pair r = return_ptr_and_i32(q, res); + assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10); + assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10); + } + + { + std::pair r = return_ptr_and_i64(q, res); + assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10); + assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10); + } + } +} + +int main(void) { + test_simple_constructors(); + test_branches(); + + return 0; +} diff --git a/compiler-rt/test/dfsan/struct.c b/compiler-rt/test/dfsan/struct.c new file mode 100644 --- /dev/null +++ b/compiler-rt/test/dfsan/struct.c @@ -0,0 +1,77 @@ +// RUN: %clang_dfsan %s -o %t && %run %t + +#include +#include + +typedef struct Pair { + int i; + char *ptr; +} Pair; + +__attribute__((noinline)) +Pair make_pair(int i, char *ptr) { + Pair pair; + pair.i = i; + pair.ptr = ptr; + return pair; +} + +__attribute__((noinline)) +Pair copy_pair1(const Pair *pair0) { + Pair pair; + pair.i = pair0->i; + pair.ptr = pair0->ptr; + return pair; +} + +__attribute__((noinline)) +Pair copy_pair2(const Pair pair0) { + Pair pair; + pair.i = pair0.i; + pair.ptr = pair0.ptr; + return pair; +} + +int main(void) { + int i = 1; + char *ptr = NULL; + dfsan_label i_label = dfsan_create_label("i", 0); + dfsan_set_label(i_label, &i, sizeof(i)); + dfsan_label ptr_label = dfsan_create_label("ptr", 0); + dfsan_set_label(ptr_label, &ptr, sizeof(ptr)); + + Pair pair1 = make_pair(i, ptr); + int i1 = pair1.i; + char *ptr1 = pair1.ptr; + + dfsan_label i1_label = dfsan_read_label(&i1, sizeof(i1)); + dfsan_label ptr1_label = dfsan_read_label(&ptr1, sizeof(ptr1)); + assert(dfsan_has_label(i1_label, i_label)); + assert(dfsan_has_label(i1_label, ptr_label)); + assert(dfsan_has_label(ptr1_label, i_label)); + assert(dfsan_has_label(ptr1_label, ptr_label)); + + Pair pair2 = copy_pair1(&pair1); + int i2 = pair2.i; + char *ptr2 = pair2.ptr; + + dfsan_label i2_label = dfsan_read_label(&i2, sizeof(i2)); + dfsan_label ptr2_label = dfsan_read_label(&ptr2, sizeof(ptr2)); + assert(dfsan_has_label(i2_label, i_label)); + assert(dfsan_has_label(i2_label, ptr_label)); + assert(dfsan_has_label(ptr2_label, i_label)); + assert(dfsan_has_label(ptr2_label, ptr_label)); + + Pair pair3 = copy_pair2(pair1); + int i3 = pair3.i; + char *ptr3 = pair3.ptr; + + dfsan_label i3_label = dfsan_read_label(&i3, sizeof(i3)); + dfsan_label ptr3_label = dfsan_read_label(&ptr3, sizeof(ptr3)); + assert(dfsan_has_label(i3_label, i_label)); + assert(dfsan_has_label(i3_label, ptr_label)); + assert(dfsan_has_label(ptr3_label, i_label)); + assert(dfsan_has_label(ptr3_label, ptr_label)); + + return 0; +}