Skip to content

Commit 3c44177

Browse files
committed
Add unit tests
1 parent b2753fc commit 3c44177

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// RUN: %check_clang_tidy %s modernize-replace-memcpy-with-std-copy %t
2+
3+
// CHECK-FIXES: #include <algorithm>
4+
5+
namespace {
6+
7+
using size_t = decltype(sizeof(int));
8+
9+
namespace std {
10+
typedef long long int64_t;
11+
typedef short int16_t;
12+
typedef char int8_t;
13+
14+
void *memcpy(void *__restrict dest, const void *__restrict src, size_t n);
15+
16+
template <typename T> struct vector {
17+
vector(size_t);
18+
19+
T *data();
20+
size_t size() const;
21+
void resize(size_t);
22+
using value_type = T;
23+
};
24+
25+
size_t size(void *);
26+
27+
size_t strlen(const char *);
28+
} // namespace std
29+
30+
void *memcpy(void *__restrict dest, const void *__restrict src, size_t n);
31+
} // namespace
32+
33+
void notSupportedEx() {
34+
char source[] = "once upon a daydream...", dest[4];
35+
36+
auto *primitiveDest = new std::int8_t;
37+
std::memcpy(primitiveDest, source, sizeof primitiveDest);
38+
39+
auto *primitiveDest2 = new std::int16_t;
40+
std::memcpy(primitiveDest2, source, sizeof primitiveDest);
41+
std::memcpy(primitiveDest2, source, sizeof primitiveDest2);
42+
43+
double d = 0.1;
44+
std::int64_t n;
45+
// don't warn on calls over non-sequences
46+
std::memcpy(&n, &d, sizeof d);
47+
48+
// object creation in destination buffer
49+
struct S {
50+
int x{42};
51+
void *operator new(size_t, void *) noexcept { return nullptr; }
52+
} s;
53+
alignas(S) char buf[sizeof(S)];
54+
S *ps = new (buf) S; // placement new
55+
// // don't warn on calls over non-sequences
56+
std::memcpy(ps, &s, sizeof s);
57+
58+
const char *pSource = "once upon a daydream...";
59+
char *pDest = new char[4];
60+
std::memcpy(dest, pSource, sizeof dest);
61+
std::memcpy(pDest, source, 4);
62+
}
63+
64+
void noFixItEx() {
65+
char source[] = "once upon a daydream...", dest[4];
66+
67+
// no FixIt when return value is used
68+
auto *ptr = std::memcpy(dest, source, sizeof dest);
69+
// CHECK-MESSAGES: [[@LINE-1]]:20: warning: prefer std::copy_n to memcpy
70+
71+
std::vector<std::int16_t> vec_i16(4);
72+
// not a supported type, should be a sequence of bytes, otherwise it is difficult to compute the n in copy_n
73+
std::memcpy(vec_i16.data(), source,
74+
vec_i16.size() * sizeof(decltype(vec_i16)::value_type));
75+
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: prefer std::copy_n to memcpy
76+
}
77+
78+
void sequenceOfBytesEx() {
79+
// the check should support memcpy conversion for the following types:
80+
// T[]
81+
// std::vector<T>
82+
// std::span<T>
83+
// std::deque<T>
84+
// std::array<T, _>
85+
// std::string
86+
// std::string_view
87+
// where T is byte-like
88+
89+
char source[] = "once upon a daydream...", dest[4];
90+
std::memcpy(dest, source, sizeof dest);
91+
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: prefer std::copy_n to memcpy
92+
// CHECK-FIXES: std::copy_n(std::begin(source), std::size(dest), std::begin(dest));
93+
94+
// __jm__ warn on global call as well
95+
memcpy(dest, source, sizeof dest);
96+
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: prefer std::copy_n to memcpy
97+
// CHECK-FIXES: std::copy_n(std::begin(source), std::size(dest), std::begin(dest));
98+
99+
std::vector<char> vec_i8(4);
100+
std::memcpy(vec_i8.data(), source, vec_i8.size());
101+
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: prefer std::copy_n to memcpy
102+
// CHECK-FIXES: std::copy_n(std::begin(source), std::size(vec_i8), std::begin(vec_i8));
103+
104+
// __jm__ make configurable whether stl containers should use members or free fns.
105+
// __jm__ for now use free fns. only
106+
107+
std::memcpy(dest, vec_i8.data(), vec_i8.size());
108+
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: prefer std::copy_n to memcpy
109+
// CHECK-FIXES: std::copy_n(std::begin(vec_i8), std::size(vec_i8), std::begin(dest));
110+
std::memcpy(dest, vec_i8.data(), sizeof(dest));
111+
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: prefer std::copy_n to memcpy
112+
// CHECK-FIXES: std::copy_n(vec_i8.data(), std::size(dest), std::begin(dest));
113+
std::memcpy(dest, vec_i8.data(), std::size(dest));
114+
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: prefer std::copy_n to memcpy
115+
// CHECK-FIXES: std::copy_n(std::begin(source), std::size(vec_i8), std::begin(vec_i8));
116+
117+
std::memcpy(dest, vec_i8.data(), 1 + vec_i8.size() / 2);
118+
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: prefer std::copy_n to memcpy
119+
// CHECK-FIXES: std::copy_n(std::begin(vec_i8), 1 + std::size(vec_i8) / 2, std::begin(dest));
120+
std::memcpy(dest, vec_i8.data(), 1 + sizeof(dest) / 2);
121+
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: prefer std::copy_n to memcpy
122+
// CHECK-FIXES: std::copy_n(vec_i8.data(), 1 + std::size(dest) / 2, std::begin(dest));
123+
std::memcpy(dest, vec_i8.data(), 1 + std::size(dest) / 2);
124+
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: prefer std::copy_n to memcpy
125+
// CHECK-FIXES: std::copy_n(std::begin(source), 1 + std::size(dest) / 2, std::begin(vec_i8));
126+
}
127+
128+
// void uninitialized_copy_ex() {
129+
// std::vector<std::string> v = {"This", "is", "an", "example"};
130+
131+
// std::string* p;
132+
// std::size_t sz;
133+
// std::tie(p, sz) = std::get_temporary_buffer<std::string>(v.size());
134+
// sz = std::min(sz, v.size());
135+
136+
// std::uninitialized_copy_n(v.begin(), sz, p);
137+
138+
// for (std::string* i = p; i != p + sz; ++i)
139+
// {
140+
// std::cout << *i << ' ';
141+
// i->~basic_string<char>();
142+
// }
143+
// std::cout << '\n';
144+
145+
// std::return_temporary_buffer(p);
146+
// }

0 commit comments

Comments
 (0)