diff --git a/libcc2rs/src/alloc.rs b/libcc2rs/src/alloc.rs index 4c643188..52b6d6c5 100644 --- a/libcc2rs/src/alloc.rs +++ b/libcc2rs/src/alloc.rs @@ -1,6 +1,28 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. +use crate::rc::{AnyPtr, Ptr}; + +pub fn malloc_refcount(_a0: usize) -> AnyPtr { + todo!("malloc_refcount") +} + +pub fn free_refcount(_a0: AnyPtr) { + todo!("free_refcount") +} + +pub fn realloc_refcount(_a0: AnyPtr, _a1: usize) -> AnyPtr { + todo!("realloc_refcount") +} + +pub fn calloc_refcount(_a0: usize, _a1: usize) -> AnyPtr { + todo!("calloc_refcount") +} + +pub fn strdup_refcount(_a0: Ptr) -> Ptr { + todo!("strdup_refcount") +} + /// # Safety /// /// Same contract as C's `malloc`. diff --git a/rules/cstdlib/tgt_refcount.rs b/rules/cstdlib/tgt_refcount.rs new file mode 100644 index 00000000..060dd534 --- /dev/null +++ b/rules/cstdlib/tgt_refcount.rs @@ -0,0 +1,20 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn f2(a0: AnyPtr) { + libcc2rs::free_refcount(a0) +} + +fn f3(a0: usize) -> AnyPtr { + libcc2rs::malloc_refcount(a0) +} + +fn f4(a0: AnyPtr, a1: usize) -> AnyPtr { + libcc2rs::realloc_refcount(a0, a1) +} + +fn f5(a0: usize, a1: usize) -> AnyPtr { + libcc2rs::calloc_refcount(a0, a1) +} diff --git a/rules/cstring/tgt_refcount.rs b/rules/cstring/tgt_refcount.rs index e2f34fcc..5d2eb6c4 100644 --- a/rules/cstring/tgt_refcount.rs +++ b/rules/cstring/tgt_refcount.rs @@ -25,3 +25,7 @@ fn f4(a0: AnyPtr, a1: AnyPtr, a2: usize) -> AnyPtr { unsafe fn f7(a0: Ptr) -> usize { a0.to_string_iterator().count() } + +fn f15(a0: Ptr) -> Ptr { + libcc2rs::strdup_refcount(a0) +} diff --git a/rules/src/modules.rs b/rules/src/modules.rs index b05d690c..53112eed 100644 --- a/rules/src/modules.rs +++ b/rules/src/modules.rs @@ -26,6 +26,8 @@ pub mod carray_tgt_refcount; pub mod carray_tgt_unsafe; #[path = r#"../cmath/tgt_unsafe.rs"#] pub mod cmath_tgt_unsafe; +#[path = r#"../cstdlib/tgt_refcount.rs"#] +pub mod cstdlib_tgt_refcount; #[path = r#"../cstdlib/tgt_unsafe.rs"#] pub mod cstdlib_tgt_unsafe; #[path = r#"../cstring/tgt_refcount.rs"#] diff --git a/tests/unit/malloc_realloc_free.c b/tests/unit/malloc_realloc_free.c index 643f8d95..9edb3097 100644 --- a/tests/unit/malloc_realloc_free.c +++ b/tests/unit/malloc_realloc_free.c @@ -1,4 +1,4 @@ -// no-compile: refcount +// panic: refcount #include #include diff --git a/tests/unit/out/refcount/malloc_realloc_free.rs b/tests/unit/out/refcount/malloc_realloc_free.rs new file mode 100644 index 00000000..d07cebe5 --- /dev/null +++ b/tests/unit/out/refcount/malloc_realloc_free.rs @@ -0,0 +1,151 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; + let p: Value> = Rc::new(RefCell::new( + libcc2rs::malloc_refcount(::std::mem::size_of::()).reinterpret_cast::(), + )); + (*p.borrow()).write(42); + assert!((((((*p.borrow()).read()) == 42) as i32) != 0)); + libcc2rs::free_refcount(((*p.borrow()).clone() as Ptr).to_any()); + let arr: Value> = Rc::new(RefCell::new( + libcc2rs::malloc_refcount( + (4_usize).wrapping_mul((::std::mem::size_of::() as usize)), + ) + .reinterpret_cast::(), + )); + let i: Value = Rc::new(RefCell::new(0)); + 'loop_: while ((((*i.borrow()) < 4) as i32) != 0) { + let __rhs = ((*i.borrow()) * 10); + (*arr.borrow()).offset((*i.borrow()) as isize).write(__rhs); + (*i.borrow_mut()).postfix_inc(); + } + assert!((((((*arr.borrow()).offset((0) as isize).read()) == 0) as i32) != 0)); + assert!((((((*arr.borrow()).offset((3) as isize).read()) == 30) as i32) != 0)); + libcc2rs::free_refcount(((*arr.borrow()).clone() as Ptr).to_any()); + let grow: Value> = Rc::new(RefCell::new( + libcc2rs::malloc_refcount( + (2_usize).wrapping_mul((::std::mem::size_of::() as usize)), + ) + .reinterpret_cast::(), + )); + (*grow.borrow()).offset((0) as isize).write(1); + (*grow.borrow()).offset((1) as isize).write(2); + let __rhs = libcc2rs::realloc_refcount( + ((*grow.borrow()).clone() as Ptr).to_any(), + (4_usize).wrapping_mul((::std::mem::size_of::() as usize)), + ) + .reinterpret_cast::(); + (*grow.borrow_mut()) = __rhs; + (*grow.borrow()).offset((2) as isize).write(3); + (*grow.borrow()).offset((3) as isize).write(4); + assert!((((((*grow.borrow()).offset((0) as isize).read()) == 1) as i32) != 0)); + assert!((((((*grow.borrow()).offset((1) as isize).read()) == 2) as i32) != 0)); + assert!((((((*grow.borrow()).offset((2) as isize).read()) == 3) as i32) != 0)); + assert!((((((*grow.borrow()).offset((3) as isize).read()) == 4) as i32) != 0)); + libcc2rs::free_refcount(((*grow.borrow()).clone() as Ptr).to_any()); + let zeros: Value> = Rc::new(RefCell::new( + libcc2rs::calloc_refcount(4_usize, ::std::mem::size_of::()) + .reinterpret_cast::(), + )); + let i: Value = Rc::new(RefCell::new(0)); + 'loop_: while ((((*i.borrow()) < 4) as i32) != 0) { + assert!( + (((((*zeros.borrow()).offset((*i.borrow()) as isize).read()) == 0) as i32) != 0) + ); + (*i.borrow_mut()).postfix_inc(); + } + libcc2rs::free_refcount(((*zeros.borrow()).clone() as Ptr).to_any()); + } + let pmalloc: Value AnyPtr>> = + Rc::new(RefCell::new(FnPtr:: AnyPtr>::new( + libcc2rs::malloc_refcount, + ))); + let pfree: Value> = Rc::new(RefCell::new(FnPtr::::new( + libcc2rs::free_refcount, + ))); + let prealloc: Value AnyPtr>> = + Rc::new(RefCell::new(FnPtr:: AnyPtr>::new( + libcc2rs::realloc_refcount, + ))); + let pcalloc: Value AnyPtr>> = + Rc::new(RefCell::new(FnPtr:: AnyPtr>::new( + libcc2rs::calloc_refcount, + ))); + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; + let p: Value> = Rc::new(RefCell::new( + ({ (*(*pmalloc.borrow()))(::std::mem::size_of::()) }).reinterpret_cast::(), + )); + (*p.borrow()).write(42); + assert!((((((*p.borrow()).read()) == 42) as i32) != 0)); + ({ (*(*pfree.borrow()))(((*p.borrow()).clone() as Ptr).to_any()) }); + let arr: Value> = Rc::new(RefCell::new( + ({ + (*(*pmalloc.borrow()))( + (4_usize).wrapping_mul((::std::mem::size_of::() as usize)), + ) + }) + .reinterpret_cast::(), + )); + let i: Value = Rc::new(RefCell::new(0)); + 'loop_: while ((((*i.borrow()) < 4) as i32) != 0) { + let __rhs = ((*i.borrow()) * 10); + (*arr.borrow()).offset((*i.borrow()) as isize).write(__rhs); + (*i.borrow_mut()).postfix_inc(); + } + assert!((((((*arr.borrow()).offset((0) as isize).read()) == 0) as i32) != 0)); + assert!((((((*arr.borrow()).offset((3) as isize).read()) == 30) as i32) != 0)); + ({ (*(*pfree.borrow()))(((*arr.borrow()).clone() as Ptr).to_any()) }); + let grow: Value> = Rc::new(RefCell::new( + ({ + (*(*pmalloc.borrow()))( + (2_usize).wrapping_mul((::std::mem::size_of::() as usize)), + ) + }) + .reinterpret_cast::(), + )); + (*grow.borrow()).offset((0) as isize).write(1); + (*grow.borrow()).offset((1) as isize).write(2); + let __rhs = ({ + (*(*prealloc.borrow()))( + ((*grow.borrow()).clone() as Ptr).to_any(), + (4_usize).wrapping_mul((::std::mem::size_of::() as usize)), + ) + }) + .reinterpret_cast::(); + (*grow.borrow_mut()) = __rhs; + (*grow.borrow()).offset((2) as isize).write(3); + (*grow.borrow()).offset((3) as isize).write(4); + assert!((((((*grow.borrow()).offset((0) as isize).read()) == 1) as i32) != 0)); + assert!((((((*grow.borrow()).offset((1) as isize).read()) == 2) as i32) != 0)); + assert!((((((*grow.borrow()).offset((2) as isize).read()) == 3) as i32) != 0)); + assert!((((((*grow.borrow()).offset((3) as isize).read()) == 4) as i32) != 0)); + ({ (*(*pfree.borrow()))(((*grow.borrow()).clone() as Ptr).to_any()) }); + let zeros: Value> = Rc::new(RefCell::new( + ({ (*(*pcalloc.borrow()))(4_usize, ::std::mem::size_of::()) }) + .reinterpret_cast::(), + )); + let i: Value = Rc::new(RefCell::new(0)); + 'loop_: while ((((*i.borrow()) < 4) as i32) != 0) { + assert!( + (((((*zeros.borrow()).offset((*i.borrow()) as isize).read()) == 0) as i32) != 0) + ); + (*i.borrow_mut()).postfix_inc(); + } + ({ (*(*pfree.borrow()))(((*zeros.borrow()).clone() as Ptr).to_any()) }); + } + return 0; +} diff --git a/tests/unit/out/refcount/union_flex_array_member.rs b/tests/unit/out/refcount/union_flex_array_member.rs new file mode 100644 index 00000000..6bf1107e --- /dev/null +++ b/tests/unit/out/refcount/union_flex_array_member.rs @@ -0,0 +1,145 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub struct anon_0 { + __bytes: Value>, +} +impl anon_0 { + pub fn bytes(&self) -> Ptr { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } + pub fn aligner(&self) -> Ptr { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } +} +impl Clone for anon_0 { + fn clone(&self) -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(self.__bytes.borrow().clone())), + } + } +} +impl Default for anon_0 { + fn default() -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(Box::from([0u8; 8]))), + } + } +} +impl ByteRepr for anon_0 { + fn byte_size() -> usize { + 8 + } + fn to_bytes(&self, buf: &mut [u8]) { + buf.copy_from_slice(&self.__bytes.borrow()); + } + fn from_bytes(buf: &[u8]) -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(Box::from(buf))), + } + } +} +#[derive(Default)] +pub struct node { + pub len: Value, + pub pos: Value, + pub x: Value, +} +impl Clone for node { + fn clone(&self) -> Self { + Self { + len: Rc::new(RefCell::new((*self.len.borrow()).clone())), + pos: Rc::new(RefCell::new((*self.pos.borrow()).clone())), + x: Rc::new(RefCell::new((*self.x.borrow()).clone())), + } + } +} +impl ByteRepr for node { + fn byte_size() -> usize { + 24 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.len.borrow()).to_bytes(&mut buf[0..8]); + (*self.pos.borrow()).to_bytes(&mut buf[8..16]); + (*self.x.borrow()).to_bytes(&mut buf[16..24]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + len: Rc::new(RefCell::new(::from_bytes(&buf[0..8]))), + pos: Rc::new(RefCell::new(::from_bytes(&buf[8..16]))), + x: Rc::new(RefCell::new(::from_bytes(&buf[16..24]))), + } + } +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let tail_size: Value = Rc::new(RefCell::new(32_usize)); + let n: Value> = Rc::new(RefCell::new( + libcc2rs::malloc_refcount( + ((24usize as u64).wrapping_add(((*tail_size.borrow()) as u64)) as usize), + ) + .reinterpret_cast::(), + )); + (*(*(*n.borrow()).upgrade().deref()).len.borrow_mut()) = (*tail_size.borrow()); + let i: Value = Rc::new(RefCell::new(0_usize)); + 'loop_: while ((((*i.borrow()) < (*tail_size.borrow())) as i32) != 0) { + let __rhs = (((*i.borrow()) & 255_usize) as u8); + ((*(*(*n.borrow()).upgrade().deref()).x.borrow()) + .bytes() + .reinterpret_cast::() as Ptr) + .offset((*i.borrow()) as isize) + .write(__rhs); + (*i.borrow_mut()).postfix_inc(); + } + let i: Value = Rc::new(RefCell::new(0_usize)); + 'loop_: while ((((*i.borrow()) < (*tail_size.borrow())) as i32) != 0) { + assert!( + ((({ + let _lhs = ((((*(*(*n.borrow()).upgrade().deref()).x.borrow()) + .bytes() + .reinterpret_cast::() as Ptr) + .offset((*i.borrow()) as isize) + .read()) as i32); + _lhs == ((((*i.borrow()) & 255_usize) as u8) as i32) + }) as i32) + != 0) + ); + (*i.borrow_mut()).postfix_inc(); + } + let p: Value> = Rc::new(RefCell::new( + (((*(*(*n.borrow()).upgrade().deref()).x.borrow()) + .bytes() + .reinterpret_cast::() as Ptr) + .offset((10) as isize)), + )); + assert!(((((((*p.borrow()).read()) as i32) == 10) as i32) != 0)); + (*p.borrow()).write(170_u8); + assert!( + (((((((*(*(*n.borrow()).upgrade().deref()).x.borrow()) + .bytes() + .reinterpret_cast::() as Ptr::) + .offset((10) as isize) + .read()) as i32) + == 170) as i32) + != 0) + ); + (*(*(*n.borrow()).upgrade().deref()).pos.borrow_mut()) = 20_usize; + let q: Value> = Rc::new(RefCell::new( + (((*(*(*n.borrow()).upgrade().deref()).x.borrow()) + .bytes() + .reinterpret_cast::() as Ptr) + .offset((*(*(*n.borrow()).upgrade().deref()).pos.borrow()) as isize)), + )); + assert!(((((((*q.borrow()).read()) as i32) == 20) as i32) != 0)); + (*q.borrow()).write(187_u8); + assert!(((((((*q.borrow()).read()) as i32) == 187) as i32) != 0)); + libcc2rs::free_refcount(((*n.borrow()).clone() as Ptr).to_any()); + return 0; +} diff --git a/tests/unit/union_flex_array_member.c b/tests/unit/union_flex_array_member.c index 7a41d456..68247d11 100644 --- a/tests/unit/union_flex_array_member.c +++ b/tests/unit/union_flex_array_member.c @@ -1,4 +1,4 @@ -// no-compile: refcount +// panic: refcount #include #include #include