Skip to content

Commit a50ac5a

Browse files
authored
Add qsort and bsearch safe rules (#258)
1 parent d565ddb commit a50ac5a

3 files changed

Lines changed: 171 additions & 1 deletion

File tree

rules/cstdlib/tgt_refcount.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,47 @@ fn f4(a0: AnyPtr, a1: usize) -> AnyPtr {
1818
fn f5(a0: usize, a1: usize) -> AnyPtr {
1919
libcc2rs::calloc_refcount(a0, a1)
2020
}
21+
22+
fn f8(a0: AnyPtr, a1: AnyPtr, a2: usize, a3: usize, a4: fn(AnyPtr, AnyPtr) -> i32) -> AnyPtr {
23+
let __base = a1.reinterpret_cast::<u8>();
24+
let mut __lo: isize = 0;
25+
let mut __hi: isize = a2 as isize - 1;
26+
let mut __found = AnyPtr::default();
27+
while __lo <= __hi && __found.is_null() {
28+
let __mid = __lo + (__hi - __lo) / 2;
29+
let __elem = __base.offset(__mid as usize * a3);
30+
let __r = a4(a0.clone(), __elem.to_any());
31+
if __r == 0 {
32+
__found = __elem.to_any();
33+
} else if __r < 0 {
34+
__hi = __mid - 1;
35+
} else {
36+
__lo = __mid + 1;
37+
}
38+
}
39+
__found
40+
}
41+
42+
fn f9(a0: AnyPtr, a1: usize, a2: usize, a3: fn(AnyPtr, AnyPtr) -> i32) {
43+
let __base = a0.reinterpret_cast::<u8>();
44+
for __i in 0..a1 {
45+
let mut __min = __i;
46+
for __j in (__i + 1)..a1 {
47+
if a3(
48+
__base.offset(__j * a2).to_any(),
49+
__base.offset(__min * a2).to_any(),
50+
) < 0
51+
{
52+
__min = __j;
53+
}
54+
}
55+
if __min != __i {
56+
for __b in 0..a2 {
57+
let __x = __base.offset(__i * a2 + __b).read();
58+
let __y = __base.offset(__min * a2 + __b).read();
59+
__base.offset(__i * a2 + __b).write(__y);
60+
__base.offset(__min * a2 + __b).write(__x);
61+
}
62+
}
63+
}
64+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
extern crate libcc2rs;
2+
use libcc2rs::*;
3+
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::io::prelude::*;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::AsFd;
8+
use std::rc::{Rc, Weak};
9+
pub fn cmp_int_0(a: AnyPtr, b: AnyPtr) -> i32 {
10+
let a: Value<AnyPtr> = Rc::new(RefCell::new(a));
11+
let b: Value<AnyPtr> = Rc::new(RefCell::new(b));
12+
let x: Value<i32> = Rc::new(RefCell::new(
13+
((*a.borrow()).reinterpret_cast::<i32>().read()),
14+
));
15+
let y: Value<i32> = Rc::new(RefCell::new(
16+
((*b.borrow()).reinterpret_cast::<i32>().read()),
17+
));
18+
return ((((*x.borrow()) > (*y.borrow())) as i32) - (((*x.borrow()) < (*y.borrow())) as i32));
19+
}
20+
pub fn main() {
21+
std::process::exit(main_0());
22+
}
23+
fn main_0() -> i32 {
24+
let arr: Value<Box<[i32]>> = Rc::new(RefCell::new(Box::new([5, 2, 9, 1, 7, 3, 8, 4])));
25+
{
26+
let __base = ((arr.as_pointer() as Ptr<i32>) as Ptr<i32>)
27+
.to_any()
28+
.reinterpret_cast::<u8>();
29+
for __i in 0..8_usize {
30+
let mut __min = __i;
31+
for __j in (__i + 1)..8_usize {
32+
if cmp_int_0(
33+
__base.offset(__j * ::std::mem::size_of::<i32>()).to_any(),
34+
__base.offset(__min * ::std::mem::size_of::<i32>()).to_any(),
35+
) < 0
36+
{
37+
__min = __j;
38+
}
39+
}
40+
if __min != __i {
41+
for __b in 0..::std::mem::size_of::<i32>() {
42+
let __x = __base
43+
.offset(__i * ::std::mem::size_of::<i32>() + __b)
44+
.read();
45+
let __y = __base
46+
.offset(__min * ::std::mem::size_of::<i32>() + __b)
47+
.read();
48+
__base
49+
.offset(__i * ::std::mem::size_of::<i32>() + __b)
50+
.write(__y);
51+
__base
52+
.offset(__min * ::std::mem::size_of::<i32>() + __b)
53+
.write(__x);
54+
}
55+
}
56+
}
57+
};
58+
let i: Value<i32> = Rc::new(RefCell::new(0));
59+
'loop_: while ((((*i.borrow()) < 7) as i32) != 0) {
60+
assert!(
61+
((((*arr.borrow())[(*i.borrow()) as usize]
62+
<= (*arr.borrow())[((*i.borrow()) + 1) as usize]) as i32)
63+
!= 0)
64+
);
65+
(*i.borrow_mut()).prefix_inc();
66+
}
67+
let key: Value<i32> = Rc::new(RefCell::new(7));
68+
let hit: Value<Ptr<i32>> = Rc::new(RefCell::new(
69+
{
70+
let __base = ((arr.as_pointer() as Ptr<i32>) as Ptr<i32>)
71+
.to_any()
72+
.reinterpret_cast::<u8>();
73+
let mut __lo: isize = 0;
74+
let mut __hi: isize = 8_usize as isize - 1;
75+
let mut __found = AnyPtr::default();
76+
while __lo <= __hi && __found.is_null() {
77+
let __mid = __lo + (__hi - __lo) / 2;
78+
let __elem = __base.offset(__mid as usize * ::std::mem::size_of::<i32>());
79+
let __r = cmp_int_0(
80+
((key.as_pointer()) as Ptr<i32>).to_any().clone(),
81+
__elem.to_any(),
82+
);
83+
if __r == 0 {
84+
__found = __elem.to_any();
85+
} else if __r < 0 {
86+
__hi = __mid - 1;
87+
} else {
88+
__lo = __mid + 1;
89+
}
90+
}
91+
__found
92+
}
93+
.reinterpret_cast::<i32>(),
94+
));
95+
assert!((((!((*hit.borrow()).is_null())) as i32) != 0));
96+
assert!((((((*hit.borrow()).read()) == 7) as i32) != 0));
97+
let miss_key: Value<i32> = Rc::new(RefCell::new(42));
98+
let miss: Value<Ptr<i32>> = Rc::new(RefCell::new(
99+
{
100+
let __base = ((arr.as_pointer() as Ptr<i32>) as Ptr<i32>)
101+
.to_any()
102+
.reinterpret_cast::<u8>();
103+
let mut __lo: isize = 0;
104+
let mut __hi: isize = 8_usize as isize - 1;
105+
let mut __found = AnyPtr::default();
106+
while __lo <= __hi && __found.is_null() {
107+
let __mid = __lo + (__hi - __lo) / 2;
108+
let __elem = __base.offset(__mid as usize * ::std::mem::size_of::<i32>());
109+
let __r = cmp_int_0(
110+
((miss_key.as_pointer()) as Ptr<i32>).to_any().clone(),
111+
__elem.to_any(),
112+
);
113+
if __r == 0 {
114+
__found = __elem.to_any();
115+
} else if __r < 0 {
116+
__hi = __mid - 1;
117+
} else {
118+
__lo = __mid + 1;
119+
}
120+
}
121+
__found
122+
}
123+
.reinterpret_cast::<i32>(),
124+
));
125+
assert!(((((*miss.borrow()).is_null()) as i32) != 0));
126+
return 0;
127+
}

tests/unit/qsort_bsearch.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// no-compile: refcount
21
#include <assert.h>
32
#include <stdlib.h>
43
#include <string.h>

0 commit comments

Comments
 (0)