Skip to content
  •  
  •  
  •  
46 changes: 43 additions & 3 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
name: Format Check

on: [push, pull_request]
on:
push:
branches:
- master
pull_request:
branches: [ "**" ]

jobs:
format:
runs-on: ubuntu-latest
permissions:
contents: read
contents: write

steps:
- name: Checkout code
Expand All @@ -21,7 +26,35 @@ jobs:
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.95.0
components: rustfmt
components: rustfmt, clippy

- name: Setup nightly Rust for rule-preprocessor clippy
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
components: rustfmt, clippy, rustc-dev

- name: Apply C++ formatting fixes
run: find cpp2rust tests -name '*.cpp' -o -name '*.h' -o -name '*.c' | xargs clang-format -i

- name: Apply Rust lint fixes
run: |
cargo clippy --fix --allow-dirty --manifest-path rules/Cargo.toml --all-targets
cargo +nightly clippy --fix --allow-dirty --manifest-path rule-preprocessor/Cargo.toml --all-targets
cargo clippy --fix --allow-dirty --manifest-path libcc2rs/Cargo.toml --all-targets

- name: Apply Rust formatting fixes
run: |
cargo fmt --manifest-path rules/Cargo.toml
cargo fmt --manifest-path rule-preprocessor/Cargo.toml
cargo fmt --manifest-path libcc2rs/Cargo.toml
find tests -name '*.rs' -print0 | xargs -0 rustfmt

- name: Commit auto-fixes
if: github.ref != 'refs/heads/master'
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "Automatically apply formatting and lint fixes"

- name: Check C++ formatting
run: find cpp2rust tests -name '*.cpp' -o -name '*.h' -o -name '*.c' | xargs clang-format --dry-run --Werror
Expand All @@ -31,3 +64,10 @@ jobs:
cargo fmt --manifest-path rules/Cargo.toml -- --check
cargo fmt --manifest-path rule-preprocessor/Cargo.toml -- --check
cargo fmt --manifest-path libcc2rs/Cargo.toml -- --check
find tests -name '*.rs' -print0 | xargs -0 rustfmt --check

- name: Check Rust lints
run: |
cargo clippy --manifest-path rules/Cargo.toml --all-targets --all-features -- -Dwarnings
cargo +nightly clippy --manifest-path rule-preprocessor/Cargo.toml --all-targets --all-features -- -Dwarnings
cargo clippy --manifest-path libcc2rs/Cargo.toml --all-targets --all-features -- -Dwarnings
5 changes: 2 additions & 3 deletions cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ use libc::*;
extern crate libcc2rs;
use libcc2rs::*;
use std::collections::BTreeMap;
use std::rc::Rc;
use std::io::{Read, Write};
use std::io::Seek;
use std::io::{Read, Write, Seek};
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
use std::rc::Rc;
)");
}

Expand Down
9 changes: 4 additions & 5 deletions cpp2rust/converter/models/converter_refcount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,12 @@ void ConverterRefCount::EmitFilePreamble() {
StrCat(R"(
extern crate libcc2rs;
use libcc2rs::*;
use std::collections::BTreeMap;
use std::cell::RefCell;
use std::io::{Read, Write};
use std::rc::{Rc, Weak};
use std::io::Seek;
use std::os::fd::AsFd;
use std::collections::BTreeMap;
use std::io::{Read, Write, Seek};
use std::io::prelude::*;
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
)");
}

Expand Down
5 changes: 5 additions & 0 deletions libcc2rs/src/compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ extern "C" {
fn platform_malloc_size(ptr: *const c_void) -> usize;
}

/// # Safety
///
/// The pointer `ptr` must be a pointer to a block of memory allocated by
/// the appropriate allocator (e.g., `malloc`).
// The memory must not have been deallocated.
pub unsafe fn malloc_usable_size(ptr: *mut c_void) -> usize {
#[cfg(target_os = "linux")]
{
Expand Down
6 changes: 6 additions & 0 deletions libcc2rs/src/dec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ prefix_wrap_dec_impl!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
prefix_nowrap_dec_impl!(f32, f64);

pub trait UnsafePostfixDec {
/// # Safety
/// This function decrements a pointer and returns the old value.
/// The caller must ensure the pointer is valid and doesn't underflow.
unsafe fn postfix_dec(&mut self) -> Self;
}

Expand All @@ -88,6 +91,9 @@ impl<T> UnsafePostfixDec for *mut T {
}

pub trait UnsafePrefixDec {
/// # Safety
/// This function decrements a pointer and returns the new value.
/// The caller must ensure the pointer is valid and doesn't underflow.
unsafe fn prefix_dec(&mut self) -> Self;
}

Expand Down
6 changes: 6 additions & 0 deletions libcc2rs/src/inc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ postfix_wrap_inc_impl!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
postfix_nowrap_inc_impl!(f32, f64);

pub trait UnsafePostfixInc {
/// # Safety
/// This function increments a pointer and returns the old value.
/// The caller must ensure the pointer is valid and doesn't overflow.
unsafe fn postfix_inc(&mut self) -> Self;
}

Expand All @@ -99,6 +102,9 @@ impl<T> UnsafePostfixInc for *mut T {
}

pub trait UnsafePrefixInc {
/// # Safety
/// This function increments a pointer and returns the new value.
/// The caller must ensure the pointer is valid and doesn't overflow.
unsafe fn prefix_inc(&mut self) -> Self;
}

Expand Down
8 changes: 8 additions & 0 deletions libcc2rs/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,18 @@ pub fn cerr() -> Ptr<std::fs::File> {
SAFE_STDERR.with(AsPointer::as_pointer)
}

/// # Safety
///
/// The caller must ensure that the returned pointer is not used after the
// thread finishes.
pub unsafe fn cout_unsafe() -> *mut std::fs::File {
UNSAFE_STDOUT.with(UnsafeCell::get)
}

/// # Safety
///
/// The caller must ensure that the returned pointer is not used after the
// thread finishes.
pub unsafe fn cerr_unsafe() -> *mut std::fs::File {
UNSAFE_STDERR.with(UnsafeCell::get)
}
36 changes: 32 additions & 4 deletions libcc2rs/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,25 @@ impl<T> Ptr<T> {
}
}

#[inline]
pub fn is_empty(&self) -> bool {
match self.kind {
PtrKind::Null => true,
PtrKind::StackSingle(_) | PtrKind::HeapSingle(_) => false,
PtrKind::Vec(ref weak) => weak
.upgrade()
.expect("ub: dangling pointer")
.borrow()
.is_empty(),
PtrKind::StackArray(ref weak) | PtrKind::HeapArray(ref weak) => weak
.upgrade()
.expect("ub: dangling pointer")
.borrow()
.is_empty(),
PtrKind::Reinterpreted(ref data) => self.offset >= data.total_byte_len(),
}
}

#[inline]
pub fn offset(&self, offset: isize) -> Self {
let step = self.elem_step();
Expand Down Expand Up @@ -660,7 +679,9 @@ impl<T> std::ops::AddAssign<u64> for Ptr<T> {
#[inline]
fn add_assign(&mut self, other: u64) {
let step = self.elem_step();
self.offset = self.offset.wrapping_add((other as usize) * step);
self.offset = self
.offset
.wrapping_add((other as usize).wrapping_mul(step));
}
}

Expand All @@ -670,23 +691,27 @@ impl<T> std::ops::AddAssign<i32> for Ptr<T> {
let step = self.elem_step();
self.offset = self
.offset
.wrapping_add(((other as isize) * step as isize) as usize);
.wrapping_add(((other as isize).wrapping_mul(step as isize)) as usize);
}
}

impl<T> std::ops::AddAssign<u32> for Ptr<T> {
#[inline]
fn add_assign(&mut self, other: u32) {
let step = self.elem_step();
self.offset = self.offset.wrapping_add((other as usize) * step);
self.offset = self
.offset
.wrapping_add((other as usize).wrapping_mul(step));
}
}

impl<T> std::ops::AddAssign<isize> for Ptr<T> {
#[inline]
fn add_assign(&mut self, other: isize) {
let step = self.elem_step();
self.offset = self.offset.wrapping_add((other * step as isize) as usize);
self.offset = self
.offset
.wrapping_add((other.wrapping_mul(step as isize)) as usize);
}
}

Expand Down Expand Up @@ -900,6 +925,7 @@ thread_local! {
}

impl Ptr<u8> {
#[allow(clippy::explicit_counter_loop)]
pub fn memcpy(&self, src: &Self, len: usize) {
let mut dst = self.clone();
let mut i: usize = 0;
Expand All @@ -914,6 +940,7 @@ impl Ptr<u8> {
assert_eq!(i, len, "ub: memcpy");
}

#[allow(clippy::explicit_counter_loop)]
pub fn memset(&self, value: u8, num: usize) {
let mut dst = self.clone();
for _ in 0..num {
Expand All @@ -922,6 +949,7 @@ impl Ptr<u8> {
}
}

#[allow(clippy::explicit_counter_loop)]
pub fn memcmp(&self, other: &Self, len: usize) -> i32 {
let mut a = self.clone();
let mut b = other.clone();
Expand Down
13 changes: 8 additions & 5 deletions libcc2rs/src/reinterpret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,22 @@ fn slice_read_bytes<S: ByteRepr>(slice: &[S], byte_offset: usize, buf: &mut [u8]
// Only deserializes/reserializes the overlapping elements.
fn slice_write_bytes<S: ByteRepr>(slice: &mut [S], byte_offset: usize, data: &[u8]) {
let elem_size = std::mem::size_of::<S>();
let mut elem_buf = vec![0u8; elem_size];
let first_elem = byte_offset / elem_size;
let last_elem = (byte_offset + data.len()).div_ceil(elem_size);
for elem_idx in first_elem..last_elem {
let num_elem = data.len().div_ceil(elem_size);
if first_elem >= slice.len() {
panic!("ub: OOB write");
}
for (elem_idx, elem) in slice.iter_mut().enumerate().skip(first_elem).take(num_elem) {
let elem_byte_start = elem_idx * elem_size;
let mut elem_buf = vec![0u8; elem_size];
slice[elem_idx].to_bytes(&mut elem_buf);
elem.to_bytes(&mut elem_buf);
let overlap_start = byte_offset.max(elem_byte_start) - elem_byte_start;
let overlap_end =
(byte_offset + data.len()).min(elem_byte_start + elem_size) - elem_byte_start;
let data_start = byte_offset.max(elem_byte_start) - byte_offset;
elem_buf[overlap_start..overlap_end]
.copy_from_slice(&data[data_start..data_start + (overlap_end - overlap_start)]);
slice[elem_idx] = S::from_bytes(&elem_buf);
*elem = S::from_bytes(&elem_buf);
}
}

Expand Down
3 changes: 3 additions & 0 deletions libcc2rs/src/va_args.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

use std::ffi::c_void;

use crate::rc::AnyPtr;
Expand Down
11 changes: 5 additions & 6 deletions rule-preprocessor/src/syntactic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,12 +435,11 @@ impl<'a> FnIrBuilder<'a> {

let mut ctx = FragmentCtx::new(self, params, generic_names);
for child in stmt_list.syntax().children_with_tokens() {
if let ra_ap_syntax::NodeOrToken::Token(ref t) = child {
if (t.kind() == SyntaxKind::L_CURLY || t.kind() == SyntaxKind::R_CURLY)
&& t.parent().as_ref() == Some(stmt_list.syntax())
{
continue;
}
if let ra_ap_syntax::NodeOrToken::Token(ref t) = child
&& (t.kind() == SyntaxKind::L_CURLY || t.kind() == SyntaxKind::R_CURLY)
&& t.parent().as_ref() == Some(stmt_list.syntax())
{
continue;
}
ctx.visit(child);
}
Expand Down
13 changes: 6 additions & 7 deletions rules/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ fn main() {
// Collect all tgt_*.rs files
let mut files = Vec::new();
visit(&crate_root, &mut |p| {
if let Some(name) = p.file_name().and_then(|s| s.to_str()) {
if name.starts_with("tgt_") && name.ends_with(".rs") {
files.push(p.to_path_buf());
}
if let Some(name) = p.file_name().and_then(|s| s.to_str())
&& name.starts_with("tgt_")
&& name.ends_with(".rs")
{
files.push(p.to_path_buf());
}
});
files.sort();
Expand All @@ -41,9 +42,7 @@ fn main() {
.to_string_lossy()
.replace('\\', "/")
.trim_start_matches("./")
.replace('/', "_")
.replace('.', "_")
.replace('-', "_");
.replace(['/', '.', '-'], "_");

if let Some(stripped) = module_name.strip_suffix("_rs") {
module_name = stripped.to_string();
Expand Down
3 changes: 1 addition & 2 deletions tests/benchmarks/out/refcount/array_sum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use libcc2rs::*;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::io::prelude::*;
use std::io::Seek;
use std::io::{Read, Write};
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn main() {
Expand Down
3 changes: 1 addition & 2 deletions tests/benchmarks/out/refcount/bfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use libcc2rs::*;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::io::prelude::*;
use std::io::Seek;
use std::io::{Read, Write};
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
#[derive(Default)]
Expand Down
3 changes: 1 addition & 2 deletions tests/benchmarks/out/refcount/bst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use libcc2rs::*;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::io::prelude::*;
use std::io::Seek;
use std::io::{Read, Write};
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
#[derive(Default)]
Expand Down
3 changes: 1 addition & 2 deletions tests/benchmarks/out/refcount/fibonacci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use libcc2rs::*;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::io::prelude::*;
use std::io::Seek;
use std::io::{Read, Write};
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn fib_0(n: u64) -> u64 {
Expand Down
3 changes: 1 addition & 2 deletions tests/benchmarks/out/refcount/prime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use libcc2rs::*;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::io::prelude::*;
use std::io::Seek;
use std::io::{Read, Write};
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn is_prime_0(x: i32) -> bool {
Expand Down
Loading
Loading