Skip to content

Commit bd838a2

Browse files
committed
Add rules for malloc, realloc, and free
1 parent 2ade29a commit bd838a2

5 files changed

Lines changed: 183 additions & 0 deletions

File tree

rules/cstdlib/ir_unsafe.json

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,90 @@
55
"text": "std::process::abort();"
66
}
77
]
8+
},
9+
"f2": {
10+
"body": [
11+
{
12+
"text": "libc::free("
13+
},
14+
{
15+
"placeholder": {
16+
"arg": 0,
17+
"access": "read"
18+
}
19+
},
20+
{
21+
"text": ")"
22+
}
23+
],
24+
"params": {
25+
"a0": {
26+
"type": "*mut ::libc::c_void",
27+
"is_unsafe_pointer": true
28+
}
29+
}
30+
},
31+
"f3": {
32+
"body": [
33+
{
34+
"text": "libc::malloc("
35+
},
36+
{
37+
"placeholder": {
38+
"arg": 0,
39+
"access": "read"
40+
}
41+
},
42+
{
43+
"text": " as ::libc::size_t)"
44+
}
45+
],
46+
"params": {
47+
"a0": {
48+
"type": "u64"
49+
}
50+
},
51+
"return_type": {
52+
"type": "*mut ::libc::c_void",
53+
"is_unsafe_pointer": true
54+
}
55+
},
56+
"f4": {
57+
"body": [
58+
{
59+
"text": "libc::realloc("
60+
},
61+
{
62+
"placeholder": {
63+
"arg": 0,
64+
"access": "read"
65+
}
66+
},
67+
{
68+
"text": ", "
69+
},
70+
{
71+
"placeholder": {
72+
"arg": 1,
73+
"access": "read"
74+
}
75+
},
76+
{
77+
"text": " as ::libc::size_t)"
78+
}
79+
],
80+
"params": {
81+
"a0": {
82+
"type": "*mut ::libc::c_void",
83+
"is_unsafe_pointer": true
84+
},
85+
"a1": {
86+
"type": "u64"
87+
}
88+
},
89+
"return_type": {
90+
"type": "*mut ::libc::c_void",
91+
"is_unsafe_pointer": true
92+
}
893
}
994
}

rules/cstdlib/src.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@
44
#include <cstdlib>
55

66
void f1() { return std::abort(); }
7+
8+
void f2(void *a0) { return free(a0); }
9+
10+
void *f3(size_t a0) { return malloc(a0); }
11+
12+
void *f4(void *a0, size_t a1) { return realloc(a0, a1); }

rules/cstdlib/tgt_unsafe.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,15 @@
44
unsafe fn f1() {
55
std::process::abort();
66
}
7+
8+
unsafe fn f2(a0: *mut ::libc::c_void) {
9+
libc::free(a0)
10+
}
11+
12+
unsafe fn f3(a0: u64) -> *mut ::libc::c_void {
13+
libc::malloc(a0 as ::libc::size_t)
14+
}
15+
16+
unsafe fn f4(a0: *mut ::libc::c_void, a1: u64) -> *mut ::libc::c_void {
17+
libc::realloc(a0, a1 as ::libc::size_t)
18+
}

tests/unit/malloc_realloc_free.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// no-compile: refcount
2+
#include <assert.h>
3+
#include <stdlib.h>
4+
5+
int main() {
6+
int *p = (int *)malloc(sizeof(int));
7+
*p = 42;
8+
assert(*p == 42);
9+
free(p);
10+
11+
int *arr = (int *)malloc(4 * sizeof(int));
12+
for (int i = 0; i < 4; i++) {
13+
arr[i] = i * 10;
14+
}
15+
assert(arr[0] == 0);
16+
assert(arr[3] == 30);
17+
free(arr);
18+
19+
int *grow = (int *)malloc(2 * sizeof(int));
20+
grow[0] = 1;
21+
grow[1] = 2;
22+
grow = (int *)realloc(grow, 4 * sizeof(int));
23+
grow[2] = 3;
24+
grow[3] = 4;
25+
assert(grow[0] == 1);
26+
assert(grow[1] == 2);
27+
assert(grow[2] == 3);
28+
assert(grow[3] == 4);
29+
free(grow);
30+
31+
return 0;
32+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
pub fn main() {
10+
unsafe {
11+
std::process::exit(main_0() as i32);
12+
}
13+
}
14+
unsafe fn main_0() -> i32 {
15+
let mut p: *mut i32 =
16+
(libc::malloc(::std::mem::size_of::<i32>() as u64 as ::libc::size_t) as *mut i32);
17+
(*p) = 42;
18+
assert!(((((*p) == (42)) as i32) != 0));
19+
libc::free((p as *mut i32 as *mut ::libc::c_void));
20+
let mut arr: *mut i32 = (libc::malloc(
21+
(4_u64).wrapping_mul(::std::mem::size_of::<i32>() as u64 as u64) as ::libc::size_t,
22+
) as *mut i32);
23+
let mut i: i32 = 0;
24+
'loop_: while ((((i) < (4)) as i32) != 0) {
25+
(*arr.offset((i) as isize)) = ((i) * (10));
26+
i.postfix_inc();
27+
}
28+
assert!(((((*arr.offset((0) as isize)) == (0)) as i32) != 0));
29+
assert!(((((*arr.offset((3) as isize)) == (30)) as i32) != 0));
30+
libc::free((arr as *mut i32 as *mut ::libc::c_void));
31+
let mut grow: *mut i32 = (libc::malloc(
32+
(2_u64).wrapping_mul(::std::mem::size_of::<i32>() as u64 as u64) as ::libc::size_t,
33+
) as *mut i32);
34+
(*grow.offset((0) as isize)) = 1;
35+
(*grow.offset((1) as isize)) = 2;
36+
grow = (libc::realloc(
37+
(grow as *mut i32 as *mut ::libc::c_void),
38+
(4_u64).wrapping_mul(::std::mem::size_of::<i32>() as u64 as u64) as ::libc::size_t,
39+
) as *mut i32);
40+
(*grow.offset((2) as isize)) = 3;
41+
(*grow.offset((3) as isize)) = 4;
42+
assert!(((((*grow.offset((0) as isize)) == (1)) as i32) != 0));
43+
assert!(((((*grow.offset((1) as isize)) == (2)) as i32) != 0));
44+
assert!(((((*grow.offset((2) as isize)) == (3)) as i32) != 0));
45+
assert!(((((*grow.offset((3) as isize)) == (4)) as i32) != 0));
46+
libc::free((grow as *mut i32 as *mut ::libc::c_void));
47+
return 0;
48+
}

0 commit comments

Comments
 (0)