Skip to content

Commit 4a98e6e

Browse files
committed
Add strdup rules + tests
1 parent b632c50 commit 4a98e6e

7 files changed

Lines changed: 508 additions & 0 deletions

File tree

rules/cstring/ir_unsafe.json

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,246 @@
6666
"is_unsafe_pointer": true
6767
}
6868
},
69+
"f10": {
70+
"body": [
71+
{
72+
"text": "libc::memchr("
73+
},
74+
{
75+
"placeholder": {
76+
"arg": 0,
77+
"access": "read"
78+
}
79+
},
80+
{
81+
"text": " as *const ::libc::c_void, "
82+
},
83+
{
84+
"placeholder": {
85+
"arg": 1,
86+
"access": "read"
87+
}
88+
},
89+
{
90+
"text": ", "
91+
},
92+
{
93+
"placeholder": {
94+
"arg": 2,
95+
"access": "read"
96+
}
97+
},
98+
{
99+
"text": " as usize)"
100+
}
101+
],
102+
"params": {
103+
"a0": {
104+
"type": "*const u8",
105+
"is_unsafe_pointer": true
106+
},
107+
"a1": {
108+
"type": "i32"
109+
},
110+
"a2": {
111+
"type": "usize"
112+
}
113+
},
114+
"return_type": {
115+
"type": "*mut ::libc::c_void",
116+
"is_unsafe_pointer": true
117+
}
118+
},
119+
"f11": {
120+
"body": [
121+
{
122+
"text": "libc::strrchr("
123+
},
124+
{
125+
"placeholder": {
126+
"arg": 0,
127+
"access": "read"
128+
}
129+
},
130+
{
131+
"text": " as *const i8, "
132+
},
133+
{
134+
"placeholder": {
135+
"arg": 1,
136+
"access": "read"
137+
}
138+
},
139+
{
140+
"text": ") as *mut u8"
141+
}
142+
],
143+
"params": {
144+
"a0": {
145+
"type": "*const u8",
146+
"is_unsafe_pointer": true
147+
},
148+
"a1": {
149+
"type": "i32"
150+
}
151+
},
152+
"return_type": {
153+
"type": "*mut u8",
154+
"is_unsafe_pointer": true
155+
}
156+
},
157+
"f12": {
158+
"body": [
159+
{
160+
"text": "libc::memchr("
161+
},
162+
{
163+
"placeholder": {
164+
"arg": 0,
165+
"access": "read"
166+
}
167+
},
168+
{
169+
"text": " as *const ::libc::c_void, "
170+
},
171+
{
172+
"placeholder": {
173+
"arg": 1,
174+
"access": "read"
175+
}
176+
},
177+
{
178+
"text": ", "
179+
},
180+
{
181+
"placeholder": {
182+
"arg": 2,
183+
"access": "read"
184+
}
185+
},
186+
{
187+
"text": " as usize) as *const ::libc::c_void"
188+
}
189+
],
190+
"params": {
191+
"a0": {
192+
"type": "*const u8",
193+
"is_unsafe_pointer": true
194+
},
195+
"a1": {
196+
"type": "i32"
197+
},
198+
"a2": {
199+
"type": "usize"
200+
}
201+
},
202+
"return_type": {
203+
"type": "*const ::libc::c_void",
204+
"is_unsafe_pointer": true
205+
}
206+
},
207+
"f13": {
208+
"body": [
209+
{
210+
"text": "libc::strrchr("
211+
},
212+
{
213+
"placeholder": {
214+
"arg": 0,
215+
"access": "read"
216+
}
217+
},
218+
{
219+
"text": " as *const i8, "
220+
},
221+
{
222+
"placeholder": {
223+
"arg": 1,
224+
"access": "read"
225+
}
226+
},
227+
{
228+
"text": ") as *const u8"
229+
}
230+
],
231+
"params": {
232+
"a0": {
233+
"type": "*const u8",
234+
"is_unsafe_pointer": true
235+
},
236+
"a1": {
237+
"type": "i32"
238+
}
239+
},
240+
"return_type": {
241+
"type": "*const u8",
242+
"is_unsafe_pointer": true
243+
}
244+
},
245+
"f14": {
246+
"body": [
247+
{
248+
"text": "libc::strrchr("
249+
},
250+
{
251+
"placeholder": {
252+
"arg": 0,
253+
"access": "read"
254+
}
255+
},
256+
{
257+
"text": " as *const i8, "
258+
},
259+
{
260+
"placeholder": {
261+
"arg": 1,
262+
"access": "read"
263+
}
264+
},
265+
{
266+
"text": ") as *mut u8"
267+
}
268+
],
269+
"params": {
270+
"a0": {
271+
"type": "*mut u8",
272+
"is_unsafe_pointer": true
273+
},
274+
"a1": {
275+
"type": "i32"
276+
}
277+
},
278+
"return_type": {
279+
"type": "*mut u8",
280+
"is_unsafe_pointer": true
281+
}
282+
},
283+
"f15": {
284+
"body": [
285+
{
286+
"text": "libc::strdup("
287+
},
288+
{
289+
"placeholder": {
290+
"arg": 0,
291+
"access": "read"
292+
}
293+
},
294+
{
295+
"text": " as *const i8) as *mut u8"
296+
}
297+
],
298+
"params": {
299+
"a0": {
300+
"type": "*const u8",
301+
"is_unsafe_pointer": true
302+
}
303+
},
304+
"return_type": {
305+
"type": "*mut u8",
306+
"is_unsafe_pointer": true
307+
}
308+
},
69309
"f2": {
70310
"body": [
71311
{

rules/cstring/src.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,9 @@ size_t f7(const char *a0) { return strlen(a0); }
1818
int f8(const char *a0, const char *a1) { return strcmp(a0, a1); }
1919

2020
int f9(const char *a0, const char *a1, size_t a2) { return strncmp(a0, a1, a2); }
21+
22+
void *f10(const void *a0, int a1, size_t a2) { return memchr(a0, a1, a2); }
23+
24+
char *f11(const char *a0, int a1) { return strrchr(a0, a1); }
25+
26+
char *f15(const char *a0) { return strdup(a0); }

rules/cstring/tgt_unsafe.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,27 @@ unsafe fn f8(a0: *const u8, a1: *const u8) -> i32 {
5555
unsafe fn f9(a0: *const u8, a1: *const u8, a2: usize) -> i32 {
5656
libc::strncmp(a0 as *const i8, a1 as *const i8, a2 as usize)
5757
}
58+
59+
unsafe fn f10(a0: *const u8, a1: i32, a2: usize) -> *mut ::libc::c_void {
60+
libc::memchr(a0 as *const ::libc::c_void, a1, a2 as usize)
61+
}
62+
63+
unsafe fn f11(a0: *const u8, a1: i32) -> *mut u8 {
64+
libc::strrchr(a0 as *const i8, a1) as *mut u8
65+
}
66+
67+
unsafe fn f12(a0: *const u8, a1: i32, a2: usize) -> *const ::libc::c_void {
68+
libc::memchr(a0 as *const ::libc::c_void, a1, a2 as usize) as *const ::libc::c_void
69+
}
70+
71+
unsafe fn f13(a0: *const u8, a1: i32) -> *const u8 {
72+
libc::strrchr(a0 as *const i8, a1) as *const u8
73+
}
74+
75+
unsafe fn f14(a0: *mut u8, a1: i32) -> *mut u8 {
76+
libc::strrchr(a0 as *const i8, a1) as *mut u8
77+
}
78+
79+
unsafe fn f15(a0: *const u8) -> *mut u8 {
80+
libc::strdup(a0 as *const i8) as *mut u8
81+
}

tests/unit/cstring.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// no-compile: refcount
22
#include <cassert>
3+
#include <cstdlib>
34
#include <cstring>
45

56
static void test_memcpy() {
@@ -74,6 +75,44 @@ static void test_strncmp() {
7475
assert(std::strncmp(buf, p, 6) == 0);
7576
}
7677

78+
static void test_memchr() {
79+
const char data[] = {0x10, 0x20, 0x30, 0x40};
80+
const void *r = std::memchr(data, 0x30, 4);
81+
assert(r == &data[2]);
82+
assert(std::memchr(data, 0x99, 4) == nullptr);
83+
const void *p = data;
84+
std::size_t n = 4;
85+
assert(std::memchr(p, 0x10, n) == p);
86+
}
87+
88+
static void test_strrchr() {
89+
const char *s = "hello world";
90+
const char *r = std::strrchr(s, 'l');
91+
assert(r != nullptr);
92+
assert(*r == 'l');
93+
assert(r == s + 9);
94+
assert(std::strrchr(s, 'z') == nullptr);
95+
char buf[] = {'a', 'b', 'a', '\0'};
96+
assert(std::strrchr(buf, 'a') == &buf[2]);
97+
}
98+
99+
static void test_strdup() {
100+
char *d = strdup("hello");
101+
assert(d != nullptr);
102+
assert(std::strcmp(d, "hello") == 0);
103+
std::free(d);
104+
const char *p = "world";
105+
char buf[] = {'a', 'b', 'c', '\0'};
106+
char *d2 = strdup(p);
107+
assert(d2 != nullptr);
108+
assert(std::strcmp(d2, p) == 0);
109+
std::free(d2);
110+
char *d3 = strdup(buf);
111+
assert(d3 != nullptr);
112+
assert(std::strcmp(d3, buf) == 0);
113+
std::free(d3);
114+
}
115+
77116
int main() {
78117
test_memcpy();
79118
test_memset();
@@ -83,5 +122,8 @@ int main() {
83122
test_strlen();
84123
test_strcmp();
85124
test_strncmp();
125+
test_memchr();
126+
test_strrchr();
127+
test_strdup();
86128
return 0;
87129
}

0 commit comments

Comments
 (0)