xref: /llvm-project/compiler-rt/test/dfsan/pair.cpp (revision 975327a609e55ad9c53bfeee63443128ce20006c)
1*5b4dda55SGeorge Balatsouras // 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*5b4dda55SGeorge Balatsouras // RUN: %clangxx_dfsan %s -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -O1 -o %t && %run %t
36fa06628SJianzhou Zhao 
46fa06628SJianzhou Zhao #include <algorithm>
56fa06628SJianzhou Zhao #include <assert.h>
66fa06628SJianzhou Zhao #include <sanitizer/dfsan_interface.h>
76fa06628SJianzhou Zhao #include <utility>
86fa06628SJianzhou Zhao 
96fa06628SJianzhou Zhao __attribute__((noinline))
106fa06628SJianzhou Zhao std::pair<int *, int>
make_pair(int * p,int i)116fa06628SJianzhou Zhao make_pair(int *p, int i) { return {p, i}; }
126fa06628SJianzhou Zhao 
136fa06628SJianzhou Zhao __attribute__((noinline))
146fa06628SJianzhou Zhao std::pair<int *, int>
copy_pair1(const std::pair<int *,int> & pair)156fa06628SJianzhou Zhao copy_pair1(const std::pair<int *, int> &pair) {
166fa06628SJianzhou Zhao   return pair;
176fa06628SJianzhou Zhao }
186fa06628SJianzhou Zhao 
196fa06628SJianzhou Zhao __attribute__((noinline))
206fa06628SJianzhou Zhao std::pair<int *, int>
copy_pair2(std::pair<int *,int> * pair)216fa06628SJianzhou Zhao copy_pair2(std::pair<int *, int> *pair) {
226fa06628SJianzhou Zhao   return *pair;
236fa06628SJianzhou Zhao }
246fa06628SJianzhou Zhao 
256fa06628SJianzhou Zhao __attribute__((noinline))
266fa06628SJianzhou Zhao std::pair<int *, int>
copy_pair3(std::pair<int *,int> && pair)276fa06628SJianzhou Zhao copy_pair3(std::pair<int *, int> &&pair) {
286fa06628SJianzhou Zhao   return std::move(pair);
296fa06628SJianzhou Zhao }
306fa06628SJianzhou Zhao 
316fa06628SJianzhou Zhao __attribute__((noinline))
326fa06628SJianzhou Zhao std::pair<const char *, uint32_t>
return_ptr_and_i32(const char * p,uint32_t res)336fa06628SJianzhou Zhao return_ptr_and_i32(const char *p, uint32_t res) {
346fa06628SJianzhou Zhao   for (uint32_t i = 2; i < 5; i++) {
356fa06628SJianzhou Zhao     uint32_t byte = static_cast<uint8_t>(p[i]);
366fa06628SJianzhou Zhao     res += (byte - 1) << (7 * i);
376fa06628SJianzhou Zhao     if (byte < 128) {
386fa06628SJianzhou Zhao       return {p + i + 1, res};
396fa06628SJianzhou Zhao     }
406fa06628SJianzhou Zhao   }
416fa06628SJianzhou Zhao   return {nullptr, 0};
426fa06628SJianzhou Zhao }
436fa06628SJianzhou Zhao 
446fa06628SJianzhou Zhao __attribute__((noinline))
456fa06628SJianzhou Zhao std::pair<const char *, uint64_t>
return_ptr_and_i64(const char * p,uint32_t res32)466fa06628SJianzhou Zhao return_ptr_and_i64(const char *p, uint32_t res32) {
476fa06628SJianzhou Zhao   uint64_t res = res32;
486fa06628SJianzhou Zhao   for (uint32_t i = 2; i < 10; i++) {
496fa06628SJianzhou Zhao     uint64_t byte = static_cast<uint8_t>(p[i]);
506fa06628SJianzhou Zhao     res += (byte - 1) << (7 * i);
516fa06628SJianzhou Zhao     if (byte < 128) {
526fa06628SJianzhou Zhao       return {p + i + 1, res};
536fa06628SJianzhou Zhao     }
546fa06628SJianzhou Zhao   }
556fa06628SJianzhou Zhao   return {nullptr, 0};
566fa06628SJianzhou Zhao }
576fa06628SJianzhou Zhao 
test_simple_constructors()586fa06628SJianzhou Zhao void test_simple_constructors() {
596fa06628SJianzhou Zhao   int i = 1;
606fa06628SJianzhou Zhao   int *ptr = NULL;
616fa06628SJianzhou Zhao   dfsan_set_label(8, &i, sizeof(i));
626fa06628SJianzhou Zhao   dfsan_set_label(2, &ptr, sizeof(ptr));
636fa06628SJianzhou Zhao 
646fa06628SJianzhou Zhao   std::pair<int *, int> pair1 = make_pair(ptr, i);
656fa06628SJianzhou Zhao   int i1 = pair1.second;
666fa06628SJianzhou Zhao   int *ptr1 = pair1.first;
676fa06628SJianzhou Zhao 
68ea981165SJianzhou Zhao #ifdef O0
696fa06628SJianzhou Zhao   assert(dfsan_read_label(&i1, sizeof(i1)) == 10);
706fa06628SJianzhou Zhao   assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 10);
71ea981165SJianzhou Zhao #else
72ea981165SJianzhou Zhao   assert(dfsan_read_label(&i1, sizeof(i1)) == 8);
73ea981165SJianzhou Zhao   assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 2);
74ea981165SJianzhou Zhao #endif
756fa06628SJianzhou Zhao 
766fa06628SJianzhou Zhao   std::pair<int *, int> pair2 = copy_pair1(pair1);
776fa06628SJianzhou Zhao   int i2 = pair2.second;
786fa06628SJianzhou Zhao   int *ptr2 = pair2.first;
796fa06628SJianzhou Zhao 
80ea981165SJianzhou Zhao #ifdef O0
816fa06628SJianzhou Zhao   assert(dfsan_read_label(&i2, sizeof(i2)) == 10);
826fa06628SJianzhou Zhao   assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 10);
83ea981165SJianzhou Zhao #else
84ea981165SJianzhou Zhao   assert(dfsan_read_label(&i2, sizeof(i2)) == 8);
85ea981165SJianzhou Zhao   assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 2);
86ea981165SJianzhou Zhao #endif
876fa06628SJianzhou Zhao 
886fa06628SJianzhou Zhao   std::pair<int *, int> pair3 = copy_pair2(&pair1);
896fa06628SJianzhou Zhao   int i3 = pair3.second;
906fa06628SJianzhou Zhao   int *ptr3 = pair3.first;
916fa06628SJianzhou Zhao 
92ea981165SJianzhou Zhao #ifdef O0
936fa06628SJianzhou Zhao   assert(dfsan_read_label(&i3, sizeof(i3)) == 10);
946fa06628SJianzhou Zhao   assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 10);
95ea981165SJianzhou Zhao #else
96ea981165SJianzhou Zhao   assert(dfsan_read_label(&i3, sizeof(i3)) == 8);
97ea981165SJianzhou Zhao   assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 2);
98ea981165SJianzhou Zhao #endif
996fa06628SJianzhou Zhao 
1006fa06628SJianzhou Zhao   std::pair<int *, int> pair4 = copy_pair3(std::move(pair1));
1016fa06628SJianzhou Zhao   int i4 = pair4.second;
1026fa06628SJianzhou Zhao   int *ptr4 = pair4.first;
1036fa06628SJianzhou Zhao 
104ea981165SJianzhou Zhao #ifdef O0
1056fa06628SJianzhou Zhao   assert(dfsan_read_label(&i4, sizeof(i4)) == 10);
1066fa06628SJianzhou Zhao   assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 10);
107ea981165SJianzhou Zhao #else
108ea981165SJianzhou Zhao   assert(dfsan_read_label(&i4, sizeof(i4)) == 8);
109ea981165SJianzhou Zhao   assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 2);
110ea981165SJianzhou Zhao #endif
1116fa06628SJianzhou Zhao }
1126fa06628SJianzhou Zhao 
test_branches()1136fa06628SJianzhou Zhao void test_branches() {
1146fa06628SJianzhou Zhao   uint32_t res = 4;
1156fa06628SJianzhou Zhao   dfsan_set_label(8, &res, sizeof(res));
1166fa06628SJianzhou Zhao 
1176fa06628SJianzhou Zhao   char p[100];
1186fa06628SJianzhou Zhao   const char *q = p;
1196fa06628SJianzhou Zhao   dfsan_set_label(2, &q, sizeof(q));
1206fa06628SJianzhou Zhao 
1216fa06628SJianzhou Zhao   {
1226fa06628SJianzhou Zhao     std::fill_n(p, 100, static_cast<char>(128));
1236fa06628SJianzhou Zhao 
1246fa06628SJianzhou Zhao     {
1256fa06628SJianzhou Zhao       std::pair<const char *, uint32_t> r = return_ptr_and_i32(q, res);
1266fa06628SJianzhou Zhao       assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0);
1276fa06628SJianzhou Zhao       assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0);
1286fa06628SJianzhou Zhao     }
1296fa06628SJianzhou Zhao 
1306fa06628SJianzhou Zhao     {
1316fa06628SJianzhou Zhao       std::pair<const char *, uint64_t> r = return_ptr_and_i64(q, res);
1326fa06628SJianzhou Zhao       assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0);
1336fa06628SJianzhou Zhao       assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0);
1346fa06628SJianzhou Zhao     }
1356fa06628SJianzhou Zhao   }
1366fa06628SJianzhou Zhao 
1376fa06628SJianzhou Zhao   {
1386fa06628SJianzhou Zhao     std::fill_n(p, 100, 0);
1396fa06628SJianzhou Zhao 
1406fa06628SJianzhou Zhao     {
1416fa06628SJianzhou Zhao       std::pair<const char *, uint32_t> r = return_ptr_and_i32(q, res);
142ea981165SJianzhou Zhao #ifdef O0
1436fa06628SJianzhou Zhao       assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10);
1446fa06628SJianzhou Zhao       assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10);
145ea981165SJianzhou Zhao #else
146ea981165SJianzhou Zhao       assert(dfsan_read_label(&r.first, sizeof(r.first)) == 2);
147ea981165SJianzhou Zhao       assert(dfsan_read_label(&r.second, sizeof(r.second)) == 8);
148ea981165SJianzhou Zhao #endif
1496fa06628SJianzhou Zhao     }
1506fa06628SJianzhou Zhao 
1516fa06628SJianzhou Zhao     {
1526fa06628SJianzhou Zhao       std::pair<const char *, uint64_t> r = return_ptr_and_i64(q, res);
153ea981165SJianzhou Zhao #ifdef O0
1546fa06628SJianzhou Zhao       assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10);
1556fa06628SJianzhou Zhao       assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10);
156ea981165SJianzhou Zhao #else
157ea981165SJianzhou Zhao       assert(dfsan_read_label(&r.first, sizeof(r.first)) == 2);
158ea981165SJianzhou Zhao       assert(dfsan_read_label(&r.second, sizeof(r.second)) == 8);
159ea981165SJianzhou Zhao #endif
1606fa06628SJianzhou Zhao     }
1616fa06628SJianzhou Zhao   }
1626fa06628SJianzhou Zhao }
1636fa06628SJianzhou Zhao 
main(void)1646fa06628SJianzhou Zhao int main(void) {
1656fa06628SJianzhou Zhao   test_simple_constructors();
1666fa06628SJianzhou Zhao   test_branches();
1676fa06628SJianzhou Zhao 
1686fa06628SJianzhou Zhao   return 0;
1696fa06628SJianzhou Zhao }
170