diff --git a/rules/cstdlib/ir_unsafe.json b/rules/cstdlib/ir_unsafe.json index 8a8481d2..d32581ad 100644 --- a/rules/cstdlib/ir_unsafe.json +++ b/rules/cstdlib/ir_unsafe.json @@ -90,5 +90,118 @@ "type": "*mut ::libc::c_void", "is_unsafe_pointer": true } + }, + "f5": { + "body": [ + { + "text": "libc::calloc(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as ::libc::size_t, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as ::libc::size_t)" + } + ], + "params": { + "a0": { + "type": "u64" + }, + "a1": { + "type": "u64" + } + }, + "return_type": { + "type": "*mut ::libc::c_void", + "is_unsafe_pointer": true + } + }, + "f6": { + "body": [ + { + "text": "libc::getenv(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8) as *mut u8" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "*mut u8", + "is_unsafe_pointer": true + } + }, + "f7": { + "body": [ + { + "text": "libc::setenv(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 2, + "access": "read" + } + }, + { + "text": ")" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a2": { + "type": "i32" + } + }, + "return_type": { + "type": "i32" + } } } diff --git a/rules/cstdlib/src.cpp b/rules/cstdlib/src.cpp index b93859c9..d81139f3 100644 --- a/rules/cstdlib/src.cpp +++ b/rules/cstdlib/src.cpp @@ -10,3 +10,11 @@ void f2(void *a0) { return free(a0); } void *f3(size_t a0) { return malloc(a0); } void *f4(void *a0, size_t a1) { return realloc(a0, a1); } + +void *f5(size_t nmemb, size_t size) { return calloc(nmemb, size); } + +char *f6(const char *name) { return getenv(name); } + +int f7(const char *name, const char *value, int overwrite) { + return setenv(name, value, overwrite); +} diff --git a/rules/cstdlib/tgt_unsafe.rs b/rules/cstdlib/tgt_unsafe.rs index 2f7491e5..0cad5a4d 100644 --- a/rules/cstdlib/tgt_unsafe.rs +++ b/rules/cstdlib/tgt_unsafe.rs @@ -16,3 +16,15 @@ unsafe fn f3(a0: u64) -> *mut ::libc::c_void { unsafe fn f4(a0: *mut ::libc::c_void, a1: u64) -> *mut ::libc::c_void { libc::realloc(a0, a1 as ::libc::size_t) } + +unsafe fn f5(a0: u64, a1: u64) -> *mut ::libc::c_void { + libc::calloc(a0 as ::libc::size_t, a1 as ::libc::size_t) +} + +unsafe fn f6(a0: *const u8) -> *mut u8 { + libc::getenv(a0 as *const i8) as *mut u8 +} + +unsafe fn f7(a0: *const u8, a1: *const u8, a2: i32) -> i32 { + libc::setenv(a0 as *const i8, a1 as *const i8, a2) +} diff --git a/tests/unit/malloc_realloc_free.c b/tests/unit/malloc_realloc_free.c index 709855d3..afd3d9e7 100644 --- a/tests/unit/malloc_realloc_free.c +++ b/tests/unit/malloc_realloc_free.c @@ -28,5 +28,11 @@ int main() { assert(grow[3] == 4); free(grow); + int *zeros = (int *)calloc(4, sizeof(int)); + for (int i = 0; i < 4; i++) { + assert(zeros[i] == 0); + } + free(zeros); + return 0; } diff --git a/tests/unit/out/unsafe/malloc_realloc_free.rs b/tests/unit/out/unsafe/malloc_realloc_free.rs index 9bade33b..77d50740 100644 --- a/tests/unit/out/unsafe/malloc_realloc_free.rs +++ b/tests/unit/out/unsafe/malloc_realloc_free.rs @@ -44,5 +44,15 @@ unsafe fn main_0() -> i32 { assert!(((((*grow.offset((2) as isize)) == (3)) as i32) != 0)); assert!(((((*grow.offset((3) as isize)) == (4)) as i32) != 0)); libc::free((grow as *mut i32 as *mut ::libc::c_void)); + let mut zeros: *mut i32 = (libc::calloc( + 4_u64 as ::libc::size_t, + ::std::mem::size_of::() as u64 as ::libc::size_t, + ) as *mut i32); + let mut i: i32 = 0; + 'loop_: while ((((i) < (4)) as i32) != 0) { + assert!(((((*zeros.offset((i) as isize)) == (0)) as i32) != 0)); + i.postfix_inc(); + } + libc::free((zeros as *mut i32 as *mut ::libc::c_void)); return 0; } diff --git a/tests/unit/out/unsafe/stdlib_h.rs b/tests/unit/out/unsafe/stdlib_h.rs new file mode 100644 index 00000000..95df3cdb --- /dev/null +++ b/tests/unit/out/unsafe/stdlib_h.rs @@ -0,0 +1,58 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub unsafe fn test_setenv_getenv_0() { + assert!( + ((((libc::setenv( + (b"CPP2RUST_TEST_VAR\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"test_value\0".as_ptr().cast_mut()).cast_const() as *const i8, + 1 + )) == (0)) as i32) + != 0) + ); + let mut v: *const u8 = + (libc::getenv((b"CPP2RUST_TEST_VAR\0".as_ptr().cast_mut()).cast_const() as *const i8) + as *mut u8) + .cast_const(); + assert!((((!((v).is_null())) as i32) != 0)); + assert!( + ((((libc::strcmp( + v as *const i8, + (b"test_value\0".as_ptr().cast_mut()).cast_const() as *const i8 + )) == (0)) as i32) + != 0) + ); + assert!( + ((((libc::setenv( + (b"CPP2RUST_TEST_VAR\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"replaced\0".as_ptr().cast_mut()).cast_const() as *const i8, + 1 + )) == (0)) as i32) + != 0) + ); + v = (libc::getenv((b"CPP2RUST_TEST_VAR\0".as_ptr().cast_mut()).cast_const() as *const i8) + as *mut u8) + .cast_const(); + assert!((((!((v).is_null())) as i32) != 0)); + assert!( + ((((libc::strcmp( + v as *const i8, + (b"replaced\0".as_ptr().cast_mut()).cast_const() as *const i8 + )) == (0)) as i32) + != 0) + ); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + (unsafe { test_setenv_getenv_0() }); + return 0; +} diff --git a/tests/unit/stdlib_h.c b/tests/unit/stdlib_h.c new file mode 100644 index 00000000..724a9a17 --- /dev/null +++ b/tests/unit/stdlib_h.c @@ -0,0 +1,20 @@ +// no-compile: refcount +#include +#include +#include + +static void test_setenv_getenv(void) { + assert(setenv("CPP2RUST_TEST_VAR", "test_value", 1) == 0); + const char *v = getenv("CPP2RUST_TEST_VAR"); + assert(v != NULL); + assert(strcmp(v, "test_value") == 0); + assert(setenv("CPP2RUST_TEST_VAR", "replaced", 1) == 0); + v = getenv("CPP2RUST_TEST_VAR"); + assert(v != NULL); + assert(strcmp(v, "replaced") == 0); +} + +int main(void) { + test_setenv_getenv(); + return 0; +}