Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 33 additions & 32 deletions rule-preprocessor/src/syntactic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,11 @@ impl SyntacticAnalysis {
let Some(name) = fn_item.name() else { continue };
let fn_name = name.text().to_string();

if fn_name == "types" {
for (name, ir) in TypeIrBuilder::new(&fn_item).build() {
file_ir.insert(name, RuleIr::Type(ir));
}
if fn_name.starts_with('t') {
file_ir.insert(
fn_name.clone(),
RuleIr::Type(TypeIrBuilder::new(&fn_item).build()),
);
} else if fn_name.starts_with('f') {
if !cfg_matches_host(&fn_item) {
continue;
Expand Down Expand Up @@ -531,35 +532,35 @@ impl<'a> TypeIrBuilder<'a> {
Self { fn_item }
}

fn build(&self) -> Vec<(String, TypeIr)> {
let Some(body) = self.fn_item.body() else {
return Vec::new();
};
let mut results = Vec::new();
for stmt in body.syntax().descendants().filter_map(ast::LetStmt::cast) {
let Some(pat) = stmt.pat() else { continue };
let pat_text = pat.syntax().text().to_string();
if !pat_text.starts_with('t') {
continue;
}
let Some(ty) = stmt.ty() else { continue };
let Some(init) = stmt.initializer() else {
continue;
};
fn build(&self) -> TypeIr {
let ty = self
.fn_item
.ret_type()
.and_then(|rt| rt.ty())
.expect("Type rules must declare a return type");
let (is_refcount_pointer, is_unsafe_pointer) = pointer_flags(&ty);

let (is_refcount_pointer, is_unsafe_pointer) = pointer_flags(&ty);
results.push((
pat_text,
TypeIr {
init: init.syntax().text().to_string(),
type_info: TypeInfo {
ty: ty.syntax().text().to_string(),
is_refcount_pointer,
is_unsafe_pointer,
},
},
));
let stmts = self
.fn_item
.body()
.and_then(|bd| bd.stmt_list())
.expect("Types rule must have a body");
assert!(
stmts.statements().count() == 0,
"Type rules mustn't contain anything in the body besides the tail expression"
);

let init = stmts
.tail_expr()
.expect("Type rules must yield an initializer");

TypeIr {
init: init.syntax().text().to_string(),
type_info: TypeInfo {
ty: ty.syntax().text().to_string(),
is_refcount_pointer,
is_unsafe_pointer,
},
}
results
}
}
6 changes: 2 additions & 4 deletions rules/array/tgt_unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@

use libcc2rs::*;

struct T1;

fn types() {
let t1: Vec<T1> = Default::default();
fn t1<T1>() -> Vec<T1> {
Default::default()
}

unsafe fn f1<T1>(a0: Vec<T1>) -> *const T1 {
Expand Down
24 changes: 18 additions & 6 deletions rules/brotli/tgt_unsafe.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

fn types() {
let t1: ::brotli_sys::BrotliDecoderResult = ::brotli_sys::BROTLI_DECODER_RESULT_ERROR;
let t2: ::brotli_sys::BrotliEncoderMode = ::brotli_sys::BROTLI_MODE_GENERIC;
let t3: *mut ::brotli_sys::BrotliDecoderState = std::ptr::null_mut();
let t4: *const ::brotli_sys::BrotliDecoderState = std::ptr::null();
let t5: ::brotli_sys::BrotliDecoderErrorCode = ::brotli_sys::BROTLI_DECODER_NO_ERROR;
fn t1() -> ::brotli_sys::BrotliDecoderResult {
::brotli_sys::BROTLI_DECODER_RESULT_ERROR
}

fn t2() -> ::brotli_sys::BrotliEncoderMode {
::brotli_sys::BROTLI_MODE_GENERIC
}

fn t3() -> *mut ::brotli_sys::BrotliDecoderState {
std::ptr::null_mut()
}

fn t4() -> *const ::brotli_sys::BrotliDecoderState {
std::ptr::null()
}

fn t5() -> ::brotli_sys::BrotliDecoderErrorCode {
::brotli_sys::BROTLI_DECODER_NO_ERROR
}

unsafe fn f1() -> ::brotli_sys::BrotliEncoderMode {
Expand Down
9 changes: 5 additions & 4 deletions rules/carray/tgt_refcount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

use libcc2rs::*;

struct T1;
fn t1<T1>() -> Box<[Value<Box<[T1]>>]> {
Box::new([Default::default()])
}

fn types() {
let t1: Box<[Value<Box<[T1]>>]> = Box::new([Default::default()]);
let t2: Box<[Value<Box<[Value<Box<[T1]>>]>>]> = Box::new([Default::default()]);
fn t2<T1>() -> Box<[Value<Box<[Value<Box<[T1]>>]>>]> {
Box::new([Default::default()])
}
9 changes: 6 additions & 3 deletions rules/carray/tgt_unsafe.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

fn types() {
let t1: libcc2rs::IgnoreRule = libcc2rs::IgnoreRule;
let t2: libcc2rs::IgnoreRule = libcc2rs::IgnoreRule;
fn t1() -> libcc2rs::IgnoreRule {
libcc2rs::IgnoreRule
}

fn t2() -> libcc2rs::IgnoreRule {
libcc2rs::IgnoreRule
}
10 changes: 4 additions & 6 deletions rules/deque/tgt_unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@

use libcc2rs::*;

struct T1;

fn types() {
// TODO: it should be VecDeque, but we don't have the neccessary infrastructure in Ptr<> to
// make this work.
let t1: Vec<T1> = Default::default();
// TODO: it should be VecDeque, but we don't have the neccessary infrastructure in Ptr<> to
// make this work.
fn t1<T1>() -> Vec<T1> {
Default::default()
}

unsafe fn f1<T1>(a0: &mut Vec<T1>) -> *const T1 {
Expand Down
15 changes: 10 additions & 5 deletions rules/fstream/tgt_unsafe.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

fn types() -> Result<(), Box<dyn std::error::Error>> {
let t1: ::std::fs::File = ::std::fs::File::open("")?;
let t2: ::std::fs::File = ::std::fs::File::open("")?;
let t3: ::std::fs::File = ::std::fs::File::open("")?;
Ok(())
fn t1() -> ::std::fs::File {
::std::fs::File::open("").unwrap()
}

fn t2() -> ::std::fs::File {
::std::fs::File::open("").unwrap()
}

fn t3() -> ::std::fs::File {
::std::fs::File::open("").unwrap()
}

unsafe fn f1(a0: *const u8) -> ::std::fs::File {
Expand Down
6 changes: 2 additions & 4 deletions rules/initializer_list/tgt_unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@

use libcc2rs::*;

struct T1;

fn types() {
let t1: Vec<T1> = Default::default();
fn t1<T1>() -> Vec<T1> {
Default::default()
}

unsafe fn f1<T1>(a0: Vec<T1>) -> u64 {
Expand Down
9 changes: 6 additions & 3 deletions rules/iostream/tgt_refcount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ use libcc2rs::*;
use std::os::fd::AsFd;

// TODO: t2 and t3 should be translated to Ptr<dyn Traits>
fn types() {
let t2: Ptr<std::fs::File> = Ptr::null();
let t3: Ptr<std::fs::File> = Ptr::null();
fn t2() -> Ptr<std::fs::File> {
Ptr::null()
}

fn t3() -> Ptr<std::fs::File> {
Ptr::null()
}

fn f1() -> ::std::fs::File {
Expand Down
14 changes: 10 additions & 4 deletions rules/iostream/tgt_unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
use libcc2rs::*;
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};

fn t1() -> std::fs::File {
std::fs::File::open("").unwrap()
}

// TODO: t2 and t3 should be translated to *mut dyn Traits
unsafe fn types() {
let t1: std::fs::File = std::fs::File::open("").unwrap();
let t2: *mut std::fs::File = libcc2rs::cout_unsafe();
let t3: *mut std::fs::File = libcc2rs::cout_unsafe();
unsafe fn t2() -> *mut std::fs::File {
libcc2rs::cout_unsafe()
}

unsafe fn t3() -> *mut std::fs::File {
libcc2rs::cout_unsafe()
}

unsafe fn f1() -> ::std::fs::File {
Expand Down
18 changes: 10 additions & 8 deletions rules/map/tgt_refcount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ use std::cell::RefCell;
use std::collections::BTreeMap;
use std::rc::Rc;

#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
struct T1;
struct T2;

fn types() {
let t1: BTreeMap<T1, Value<T2>> = BTreeMap::new();
let t2: RefcountMapIter<T1, T2> = RefcountMapIter::null();
let t3: RefcountMapIter<T1, T2> = RefcountMapIter::null();
fn t1<T1, T2>() -> BTreeMap<T1, Value<T2>> {
BTreeMap::new()
}

fn t2<T1: Clone + Ord + 'static, T2: 'static>() -> RefcountMapIter<T1, T2> {
RefcountMapIter::null()
}

fn t3<T1: Clone + Ord + 'static, T2: 'static>() -> RefcountMapIter<T1, T2> {
RefcountMapIter::null()
}

fn f1<T1: Ord + Clone + ByteRepr + 'static, T2: Default + ByteRepr + 'static>(
Expand Down
16 changes: 9 additions & 7 deletions rules/map/tgt_unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
use libcc2rs::{MapIterator, UnsafeMapIterator};
use std::collections::BTreeMap;

#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
struct T1;
struct T2;
fn t1<T1, T2>() -> BTreeMap<T1, Box<T2>> {
BTreeMap::new()
}

fn t2<T1: Clone + Ord, T2>() -> UnsafeMapIterator<T1, T2> {
UnsafeMapIterator::null()
}

fn types() {
let t1: BTreeMap<T1, Box<T2>> = BTreeMap::new();
let t2: UnsafeMapIterator<T1, T2> = UnsafeMapIterator::null();
let t3: UnsafeMapIterator<T1, T2> = UnsafeMapIterator::null();
fn t3<T1: Clone + Ord, T2>() -> UnsafeMapIterator<T1, T2> {
UnsafeMapIterator::null()
}

unsafe fn f1<T1: Ord + Clone, T2: Default>(a0: &mut BTreeMap<T1, Box<T2>>, a1: T1) -> &mut T2 {
Expand Down
12 changes: 3 additions & 9 deletions rules/pair/tgt_refcount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,11 @@ use libcc2rs::*;
use std::cell::RefCell;
use std::rc::Rc;

#[derive(Default)]
struct T1;

#[derive(Default)]
struct T2;

fn types() {
let t1: (Value<T1>, Value<T2>) = (
fn t1<T1: Default, T2: Default>() -> (Value<T1>, Value<T2>) {
(
Rc::new(RefCell::new(T1::default())),
Rc::new(RefCell::new(T2::default())),
);
)
}

fn f1<T1, T2>(a0: (Value<T1>, Value<T2>)) -> Value<T2> {
Expand Down
10 changes: 2 additions & 8 deletions rules/pair/tgt_unsafe.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

#[derive(Default)]
struct T1;

#[derive(Default)]
struct T2;

fn types() {
let t1: (T1, T2) = <(T1, T2)>::default();
fn t1<T1: Default, T2: Default>() -> (T1, T2) {
<(T1, T2)>::default()
}

unsafe fn f1<T1, T2>(a0: (T1, T2)) -> T2 {
Expand Down
4 changes: 2 additions & 2 deletions rules/select/tgt_unsafe.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

unsafe fn types() {
let t1: ::libc::fd_set = std::mem::zeroed::<::libc::fd_set>();
unsafe fn t1() -> ::libc::fd_set {
std::mem::zeroed::<::libc::fd_set>()
}

unsafe fn f1(
Expand Down
5 changes: 2 additions & 3 deletions rules/stdio/tgt_refcount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ use libcc2rs::*;
use std::io::prelude::*;
use std::os::fd::AsFd;

fn types() -> Result<(), Box<dyn std::error::Error>> {
let t1: Ptr<::std::fs::File> = Ptr::null();
Ok(())
fn t1() -> Ptr<::std::fs::File> {
Ptr::null()
}

fn f1(a0: Ptr<u8>, a1: Ptr<u8>) -> Ptr<::std::fs::File> {
Expand Down
5 changes: 2 additions & 3 deletions rules/stdio/tgt_unsafe.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

fn types() -> Result<(), Box<dyn std::error::Error>> {
let t1: *mut ::libc::FILE = std::ptr::null_mut();
Ok(())
fn t1() -> *mut ::libc::FILE {
std::ptr::null_mut()
}

unsafe fn f1(a0: *const u8, a1: *const u8) -> *mut ::libc::FILE {
Expand Down
4 changes: 2 additions & 2 deletions rules/string/tgt_refcount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use libcc2rs::*;
use std::cell::RefCell;
use std::rc::Rc;

fn types() {
let t2: Ptr<u8> = Ptr::null();
fn t2() -> Ptr<u8> {
Ptr::null()
}

fn f1(a0: Vec<u8>, a1: usize, a2: usize) -> Vec<u8> {
Expand Down
9 changes: 6 additions & 3 deletions rules/string/tgt_unsafe.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

fn types() {
let t1: Vec<u8> = Vec::new();
let t2: *mut u8 = ::std::ptr::null_mut();
fn t1() -> Vec<u8> {
Vec::new()
}

fn t2() -> *mut u8 {
::std::ptr::null_mut()
}

unsafe fn f1(a0: Vec<u8>, a1: usize, a2: usize) -> Vec<u8> {
Expand Down
Loading
Loading