diff --git a/rules/string/tgt_refcount.rs b/rules/string/tgt_refcount.rs index 5e7f50ff0..a7b580240 100644 --- a/rules/string/tgt_refcount.rs +++ b/rules/string/tgt_refcount.rs @@ -122,7 +122,8 @@ fn f18(a0: Vec, a1: Ptr) -> bool { // TODO: This should return a0 fn f21(a0: &mut Vec, a1: usize, a2: i8) -> Vec { a0.pop(); - a0.resize(a0.len() + (a1) as usize, a2); + let __len = a0.len() + (a1) as usize; + a0.resize(__len, a2); a0.push(0); a0.clone() } diff --git a/tests/unit/out/refcount/string_repeat_append.rs b/tests/unit/out/refcount/string_repeat_append.rs new file mode 100644 index 000000000..f19eeb24f --- /dev/null +++ b/tests/unit/out/refcount/string_repeat_append.rs @@ -0,0 +1,175 @@ +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 append_to_reference_0(s: Ptr>) { + { + s.with_mut(|__v: &mut Vec| __v.pop()); + let __len = (*s.upgrade().deref()).len() + (1_usize) as usize; + s.with_mut(|__v: &mut Vec| __v.resize(__len, ('r' as i8))); + s.with_mut(|__v: &mut Vec| __v.push(0)); + (*s.upgrade().deref()).clone() + }; +} +pub fn main() { + __cpp2rust_init_globals(); + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let lengths: Value> = Rc::new(RefCell::new(Box::new([ + 0_usize, 1_usize, 2_usize, 3_usize, 7_usize, 8_usize, 15_usize, 16_usize, 31_usize, + 64_usize, + ]))); + let counts: Value> = Rc::new(RefCell::new(Box::new([ + 0_usize, 1_usize, 2_usize, 3_usize, 8_usize, 33_usize, + ]))); + let characters: Value> = Rc::new(RefCell::new(Box::new([ + 0_i8, + 1_i8, + 2_i8, + 7_i8, + 9_i8, + 10_i8, + 13_i8, + 31_i8, + 32_i8, + 42_i8, + 65_i8, + 90_i8, + 97_i8, + 100_i8, + 127_i8, + (-128_i32 as i8), + (-127_i32 as i8), + (-64_i32 as i8), + (-2_i32 as i8), + (-1_i32 as i8), + ]))); + let mut initial: [i8; 5] = [ + ('a' as i8), + 0_i8, + ('b' as i8), + (-128_i32 as i8), + (-1_i32 as i8), + ]; + let mut cases: usize = 0_usize; + 'loop_: for length in IterRange::new( + (lengths.as_pointer() as Ptr), + (lengths.as_pointer() as Ptr).offset((10_i64) as isize), + ) { + let mut length: usize = (length.read()); + 'loop_: for count in IterRange::new( + (counts.as_pointer() as Ptr), + (counts.as_pointer() as Ptr).offset((6_i64) as isize), + ) { + let mut count: usize = (count.read()); + 'loop_: for character in IterRange::new( + (characters.as_pointer() as Ptr), + (characters.as_pointer() as Ptr).offset((20_i64) as isize), + ) { + let character: Value = Rc::new(RefCell::new((character.read()))); + let mut shrink: i32 = 0; + 'loop_: while (shrink < 2) { + let s: Value> = Rc::new(RefCell::new( + vec![('x' as i8); (length) as usize] + .iter() + .cloned() + .chain(std::iter::once(0)) + .collect(), + )); + let mut i: usize = 0_usize; + 'loop_: while (i < length) { + let __rhs = initial[((i) + .wrapping_rem((::std::mem::size_of::<[i8; 5]>() as usize))) + as usize]; + (*s.borrow_mut())[i] = __rhs; + i.prefix_inc(); + } + if (shrink != 0) { + (*s.borrow_mut()).shrink_to_fit(); + } + { + (*s.borrow_mut()).pop(); + let __len = (*s.borrow()).len() + (count) as usize; + (*s.borrow_mut()).resize(__len, ({ (*character.borrow()) })); + (*s.borrow_mut()).push(0); + (*s.borrow()).clone() + }; + assert!(({ (((*s.borrow()).len() - 1) == (length).wrapping_add(count)) })); + let mut data: Ptr = s.decay(); + let mut i: usize = 0_usize; + 'loop_: while (i < (length).wrapping_add(count)) { + assert!( + ({ + ({ ((elem!(data, i).read()) as i32) } == { + ((if (i < length) { + initial[((i).wrapping_rem( + (::std::mem::size_of::<[i8; 5]>() as usize), + )) as usize] + } else { + (*character.borrow()) + }) as i32) + }) + }) + ); + i.prefix_inc(); + } + assert!(({ (((elem!(data, ((*s.borrow()).len() - 1)).read()) as i32) == 0) })); + cases.prefix_inc(); + shrink.prefix_inc(); + } + } + } + } + let mut unboxed: Vec = { + let mut __bytes = Ptr::::from_string_literal(b"a").to_c_bytes(); + __bytes.push(0); + __bytes + }; + { + unboxed.pop(); + let __len = unboxed.len() + (2_usize) as usize; + unboxed.resize(__len, ('b' as i8)); + unboxed.push(0); + unboxed.clone() + }; + assert!( + Ptr::::from_string_literal(b"abb") + .with_c_str(|__s| unboxed[..unboxed.len().saturating_sub(1)] == *__s) + ); + let indirect: Value> = Rc::new(RefCell::new({ + let mut __bytes = Ptr::::from_string_literal(b"c").to_c_bytes(); + __bytes.push(0); + __bytes + })); + ({ append_to_reference_0(indirect.as_pointer()) }); + assert!( + ({ + Ptr::::from_string_literal(b"cr").with_c_str(|__s| { + (*indirect.borrow())[..(*indirect.borrow()).len().saturating_sub(1)] == *__s + }) + }) + ); + let mut pointer: Ptr> = (indirect.as_pointer()); + { + pointer.with_mut(|__v: &mut Vec| __v.pop()); + let __len = (*pointer.upgrade().deref()).len() + (0_usize) as usize; + pointer.with_mut(|__v: &mut Vec| __v.resize(__len, ('\0' as i8))); + pointer.with_mut(|__v: &mut Vec| __v.push(0)); + (*pointer.upgrade().deref()).clone() + }; + assert!( + ({ + Ptr::::from_string_literal(b"cr").with_c_str(|__s| { + (*indirect.borrow())[..(*indirect.borrow()).len().saturating_sub(1)] == *__s + }) + }) + ); + println!("checked {} appends", cases); + return 0; +} +pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/string_repeat_append.rs b/tests/unit/out/unsafe/string_repeat_append.rs new file mode 100644 index 000000000..5ae7955d8 --- /dev/null +++ b/tests/unit/out/unsafe/string_repeat_append.rs @@ -0,0 +1,168 @@ +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 append_to_reference_0(s: *mut Vec) { + (*s).splice( + (*s).len() - 1..(*s).len() - 1, + ::std::vec::from_elem(('r' as libc::c_char), 1_usize as usize), + ); +} +pub fn main() { + unsafe { + __cpp2rust_init_globals(); + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let lengths: [usize; 10] = [ + 0_usize, 1_usize, 2_usize, 3_usize, 7_usize, 8_usize, 15_usize, 16_usize, 31_usize, + 64_usize, + ]; + let counts: [usize; 6] = [0_usize, 1_usize, 2_usize, 3_usize, 8_usize, 33_usize]; + let characters: [libc::c_char; 20] = [ + (0 as libc::c_char), + (1 as libc::c_char), + (2 as libc::c_char), + (7 as libc::c_char), + (9 as libc::c_char), + (10 as libc::c_char), + (13 as libc::c_char), + (31 as libc::c_char), + (32 as libc::c_char), + (42 as libc::c_char), + (65 as libc::c_char), + (90 as libc::c_char), + (97 as libc::c_char), + (100 as libc::c_char), + (127 as libc::c_char), + (-128_i32 as libc::c_char), + (-127_i32 as libc::c_char), + (-64_i32 as libc::c_char), + (-2_i32 as libc::c_char), + (-1_i32 as libc::c_char), + ]; + let initial: [libc::c_char; 5] = [ + ('a' as libc::c_char), + (0 as libc::c_char), + ('b' as libc::c_char), + (-128_i32 as libc::c_char), + (-1_i32 as libc::c_char), + ]; + let mut cases: usize = 0_usize; + 'loop_: for length in + IterRange::new(lengths.as_ptr(), lengths.as_ptr().offset((10_i64) as isize)) + { + let mut length: usize = (*length); + 'loop_: for count in + IterRange::new(counts.as_ptr(), counts.as_ptr().offset((6_i64) as isize)) + { + let mut count: usize = (*count); + 'loop_: for character in IterRange::new( + characters.as_ptr(), + characters.as_ptr().offset((20_i64) as isize), + ) { + let mut character: libc::c_char = (*character); + let mut shrink: i32 = 0; + 'loop_: while ((shrink) < (2)) { + let mut s: Vec = vec![('x' as libc::c_char); (length) as usize] + .iter() + .cloned() + .chain(std::iter::once(0)) + .collect(); + let mut i: usize = 0_usize; + 'loop_: while ((i) < (length)) { + s[(i)] = initial[((i) + .wrapping_rem((::std::mem::size_of::<[libc::c_char; 5]>() as usize)))]; + i.prefix_inc(); + } + if (shrink != 0) { + s.shrink_to_fit(); + } + s.splice( + s.len() - 1..s.len() - 1, + ::std::vec::from_elem(character, count as usize), + ); + assert!(((s.len() - 1) == ((length).wrapping_add(count)))); + let mut data: *const libc::c_char = (s.as_mut_ptr()).cast_const(); + let mut i: usize = 0_usize; + 'loop_: while ((i) < ((length).wrapping_add(count))) { + assert!( + (((*data.offset((i) as isize)) as i32) + == ((if ((i) < (length)) { + initial[((i).wrapping_rem( + (::std::mem::size_of::<[libc::c_char; 5]>() as usize), + ))] + } else { + character + }) as i32)) + ); + i.prefix_inc(); + } + assert!((((*data.offset((s.len() - 1) as isize)) as i32) == (0))); + cases.prefix_inc(); + shrink.prefix_inc(); + } + } + } + } + let mut unboxed: Vec = std::slice::from_raw_parts( + c"a".as_ptr(), + (0..).take_while(|&i| *c"a".as_ptr().add(i) != 0).count() + 1, + ) + .to_vec(); + unboxed.splice( + unboxed.len() - 1..unboxed.len() - 1, + ::std::vec::from_elem(('b' as libc::c_char), 2_usize as usize), + ); + assert!( + unboxed == { + std::slice::from_raw_parts( + c"abb".as_ptr(), + (0..).take_while(|&i| *c"abb".as_ptr().add(i) != 0).count() + 1, + ) + .to_vec() + } + ); + let mut indirect: Vec = std::slice::from_raw_parts( + c"c".as_ptr(), + (0..).take_while(|&i| *c"c".as_ptr().add(i) != 0).count() + 1, + ) + .to_vec(); + (unsafe { append_to_reference_0(&mut indirect) }); + assert!( + indirect == { + std::slice::from_raw_parts( + c"cr".as_ptr(), + (0..).take_while(|&i| *c"cr".as_ptr().add(i) != 0).count() + 1, + ) + .to_vec() + } + ); + let mut pointer: *mut Vec = (&mut indirect as *mut Vec); + (*pointer).splice( + (*pointer).len() - 1..(*pointer).len() - 1, + ::std::vec::from_elem(('\0' as libc::c_char), 0_usize as usize), + ); + assert!( + indirect == { + std::slice::from_raw_parts( + c"cr".as_ptr(), + (0..).take_while(|&i| *c"cr".as_ptr().add(i) != 0).count() + 1, + ) + .to_vec() + } + ); + (unsafe { + libc::printf( + c"checked %zu appends\n".as_ptr() as *const libc::c_char, + (cases), + ) + }); + return 0; +} +pub unsafe fn __cpp2rust_init_globals() {} diff --git a/tests/unit/string_repeat_append.cpp b/tests/unit/string_repeat_append.cpp new file mode 100644 index 000000000..0bf287ecd --- /dev/null +++ b/tests/unit/string_repeat_append.cpp @@ -0,0 +1,47 @@ +#include +#include +#include + +void append_to_reference(std::string &s) { s.append(1, 'r'); } + +int main() { + const std::size_t lengths[] = {0, 1, 2, 3, 7, 8, 15, 16, 31, 64}; + const std::size_t counts[] = {0, 1, 2, 3, 8, 33}; + const char characters[] = {0, 1, 2, 7, 9, 10, 13, 31, 32, 42, + 65, 90, 97, 100, 127, -128, -127, -64, -2, -1}; + const char initial[] = {'a', 0, 'b', -128, -1}; + std::size_t cases = 0; + for (std::size_t length : lengths) { + for (std::size_t count : counts) { + for (char character : characters) { + for (int shrink = 0; shrink < 2; ++shrink) { + std::string s(length, 'x'); + for (std::size_t i = 0; i < length; ++i) + s[i] = initial[i % std::size_t(sizeof(initial))]; + if (shrink) + s.shrink_to_fit(); + s.append(count, character); + assert(s.size() == length + count); + const char *data = s.data(); + for (std::size_t i = 0; i < length + count; ++i) + assert(data[i] == (i < length + ? initial[i % std::size_t(sizeof(initial))] + : character)); + assert(data[s.size()] == 0); + ++cases; + } + } + } + } + std::string unboxed = "a"; + unboxed.append(2, 'b'); + assert(unboxed == "abb"); + std::string indirect = "c"; + append_to_reference(indirect); + assert(indirect == "cr"); + std::string *pointer = &indirect; + pointer->append(std::size_t(0), '\0'); + assert(indirect == "cr"); + printf("checked %zu appends\n", cases); + return 0; +}