Skip to content

Commit 28f2e5b

Browse files
authored
Merge pull request #681 from TimDiekmann/calloc
Add `calloc`
2 parents 6871145 + d2d5f00 commit 28f2e5b

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

src/fn_call.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,21 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
9393
this.write_scalar(Scalar::Ptr(ptr.with_default_tag()), dest)?;
9494
}
9595
}
96+
"calloc" => {
97+
let items = this.read_scalar(args[0])?.to_usize(this)?;
98+
let len = this.read_scalar(args[1])?.to_usize(this)?;
99+
let bytes = items.checked_mul(len).ok_or_else(|| InterpError::Overflow(mir::BinOp::Mul))?;
100+
101+
if bytes == 0 {
102+
this.write_null(dest)?;
103+
} else {
104+
let size = Size::from_bytes(bytes);
105+
let align = this.tcx.data_layout.pointer_align.abi;
106+
let ptr = this.memory_mut().allocate(size, align, MiriMemoryKind::C.into()).with_default_tag();
107+
this.memory_mut().get_mut(ptr.alloc_id)?.write_repeat(tcx, ptr, 0, size)?;
108+
this.write_scalar(Scalar::Ptr(ptr), dest)?;
109+
}
110+
}
96111
"posix_memalign" => {
97112
let ret = this.deref_operand(args[0])?;
98113
let align = this.read_scalar(args[1])?.to_usize(this)?;

tests/run-pass/calloc.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//ignore-windows: Uses POSIX APIs
2+
3+
#![feature(rustc_private)]
4+
5+
use core::slice;
6+
7+
extern crate libc;
8+
9+
fn main() {
10+
unsafe {
11+
let p1 = libc::calloc(0, 0);
12+
assert!(p1.is_null());
13+
14+
let p2 = libc::calloc(20, 0);
15+
assert!(p2.is_null());
16+
17+
let p3 = libc::calloc(0, 20);
18+
assert!(p3.is_null());
19+
20+
let p4 = libc::calloc(4, 8);
21+
assert!(!p4.is_null());
22+
let slice = slice::from_raw_parts(p4 as *const u8, 4 * 8);
23+
assert_eq!(&slice, &[0_u8; 4 * 8]);
24+
libc::free(p4);
25+
}
26+
}

0 commit comments

Comments
 (0)