Skip to content
Closed
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
21 changes: 21 additions & 0 deletions cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ void Converter::EmitRustStructOrUnion(clang::RecordDecl *decl) {
}
AddDefaultTrait(decl);
AddByteReprTrait(decl);
AddSyncTrait(decl);
}

bool Converter::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) {
Expand Down Expand Up @@ -3470,6 +3471,26 @@ void Converter::AddDefaultTrait(const clang::RecordDecl *decl) {

void Converter::AddByteReprTrait(const clang::RecordDecl *decl) {}

static bool recordImplementsSync(const clang::RecordDecl *decl) {
for (auto field : decl->fields()) {
if (field->getType()->isPointerType()) {
return true;
}
}
return false;
}

void Converter::AddSyncTrait(const clang::RecordDecl *decl) {
if (!recordImplementsSync(decl)) {
return;
}

StrCat("\n// SAFETY: preserves unsafe C semantics; thread-safety is not "
"enforced\n");
StrCat("unsafe impl Sync for", GetRecordName(decl));
PushBrace brace(*this);
}

void Converter::ConvertUnsignedArithBinaryOperator(clang::BinaryOperator *op,
clang::Expr *expr) {
StrCat(token::kDot);
Expand Down
2 changes: 2 additions & 0 deletions cpp2rust/converter/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,8 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {

virtual void AddByteReprTrait(const clang::RecordDecl *decl);

virtual void AddSyncTrait(const clang::RecordDecl *decl);

virtual void
ConvertUnsignedArithBinaryOperator(clang::BinaryOperator *binary_operator,
clang::Expr *expr);
Expand Down
2 changes: 2 additions & 0 deletions cpp2rust/converter/models/converter_refcount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,8 @@ void ConverterRefCount::AddByteReprTrait(const clang::RecordDecl *decl) {
PushBrace brace(*this);
}

void ConverterRefCount::AddSyncTrait(const clang::RecordDecl *decl) {}

std::string
ConverterRefCount::GetSelfMaybeWithMut(const clang::CXXMethodDecl *decl) {
return "&self";
Expand Down
2 changes: 2 additions & 0 deletions cpp2rust/converter/models/converter_refcount.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class ConverterRefCount final : public Converter {

void AddByteReprTrait(const clang::RecordDecl *decl) override;

void AddSyncTrait(const clang::RecordDecl *decl) override;

void AddDefaultTrait(const clang::RecordDecl *decl) override;

void AddDefaultTraitForUnion(const clang::RecordDecl *decl) override;
Expand Down
6 changes: 6 additions & 0 deletions tests/benchmarks/out/unsafe/bfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,16 @@ impl Queue {
return ((self.back) == (0_u64));
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Queue {}
#[repr(C)]
#[derive(Copy, Clone, Default)]
pub struct GraphNode {
pub vertex: u32,
pub next: *mut GraphNode,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for GraphNode {}
#[repr(C)]
#[derive(Copy, Clone, Default)]
pub struct Graph {
Expand All @@ -60,6 +64,8 @@ impl Graph {
})) as *mut GraphNode);
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Graph {}
pub unsafe fn BFS_0(graph: *const Graph, mut start_vertex: u32) -> *mut u32 {
let mut Q: Queue = Queue {
elems: Box::leak(
Expand Down
2 changes: 2 additions & 0 deletions tests/benchmarks/out/unsafe/bst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub struct node_t {
pub right: *mut node_t,
pub value: i32,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for node_t {}
pub unsafe fn find_0(mut node: *mut node_t, mut value: i32) -> *mut node_t {
if ((value) < ((*node).value)) && (!(((*node).left).is_null())) {
return (unsafe {
Expand Down
58 changes: 58 additions & 0 deletions tests/unit/out/refcount/send_sync_in_statics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
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};
#[derive(Default)]
pub struct Entry {
pub name: Value<Ptr<u8>>,
pub p: Value<Ptr<i32>>,
}
impl Clone for Entry {
fn clone(&self) -> Self {
let mut this = Self {
name: Rc::new(RefCell::new((*self.name.borrow()).clone())),
p: Rc::new(RefCell::new((*self.p.borrow()).clone())),
};
this
}
}
impl ByteRepr for Entry {}
thread_local!(
pub static single_entry: Value<Entry> = Rc::new(RefCell::new(Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("alone"))),
p: Rc::new(RefCell::new(Default::default())),
}));
);
thread_local!(
pub static entries: Value<Box<[Entry]>> = Rc::new(RefCell::new(Box::new([
Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("first"))),
p: Rc::new(RefCell::new(Default::default())),
},
Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("second"))),
p: Rc::new(RefCell::new(Default::default())),
},
])));
);
pub fn main() {
std::process::exit(main_0());
}
fn main_0() -> i32 {
assert!((*(*single_entry.with(Value::clone).borrow()).p.borrow()).is_null());
let i: Value<i32> = Rc::new(RefCell::new(0));
'loop_: while ((*i.borrow()) < 2) {
assert!(
(*(*entries.with(Value::clone).borrow())[(*i.borrow()) as usize]
.p
.borrow())
.is_null()
);
(*i.borrow_mut()).prefix_inc();
}
return 0;
}
4 changes: 4 additions & 0 deletions tests/unit/out/unsafe/10_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub struct GraphNode {
pub dst: u32,
pub next: *mut GraphNode,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for GraphNode {}
#[repr(C)]
#[derive(Copy, Clone, Default)]
pub struct Graph {
Expand All @@ -30,6 +32,8 @@ impl Graph {
})) as *mut GraphNode);
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Graph {}
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/bst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub struct node_t {
pub right: *mut node_t,
pub value: i32,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for node_t {}
pub unsafe fn find_0(mut node: *mut node_t, mut value: i32) -> *mut node_t {
if ((value) < ((*node).value)) && (!(((*node).left).is_null())) {
return (unsafe {
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/c_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub struct Node {
pub value: i32,
pub next: *mut Node,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Node {}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum Color {
#[default]
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/clone_vs_move.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ impl Default for Foo {
}
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Foo {}
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/complex_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ impl X3 {
return self.v;
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for X3 {}
#[repr(C)]
#[derive(Copy, Clone, Default)]
pub struct X4 {
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ impl Default for Pointers {
}
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Pointers {}
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/enum_int_interop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ pub struct Entry {
pub color: Color,
pub opt: Option,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Entry {}
pub static mut global_color: Color = Color::GREEN;
pub static mut global_opt: Option = Option::OPT_B;
pub static mut global_tag: Tag = Tag::TAG_TWO;
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/enum_int_interop_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ pub struct Entry {
pub color: Color,
pub opt: Option,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Entry {}
pub static mut global_color: Color = Color::GREEN;
pub static mut global_opt: Option = Option::OPT_B;
pub static mut global_tag: Tag = Tag::TAG_TWO;
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/exprs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ impl Y {
return (&mut self.x as *mut X);
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Y {}
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/fn_ptr_cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ pub unsafe fn test_double_cast_2() {
pub struct Command {
pub data: *mut ::libc::c_void,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Command {}
pub unsafe fn test_void_ptr_to_fn_3() {
let mut cmd: Command = <Command>::default();
cmd.data = std::mem::transmute::<Option<unsafe fn(i32) -> i32>, *mut ::libc::c_void>(Some(
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/fn_ptr_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ impl Default for Handler {
}
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Handler {}
pub unsafe fn double_it_0(mut x: i32) -> i32 {
return ((x) * (2));
}
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/fn_ptr_vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ impl Default for Vtable {
}
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Vtable {}
pub static mut storage: i32 = 0_i32;
pub unsafe fn int_create_0(mut val: i32) -> *mut ::libc::c_void {
storage = val;
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/huffman.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ impl MinHeapNode {
return ((self.left).is_null()) && ((self.right).is_null());
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for MinHeapNode {}
pub unsafe fn Swap_0(a: *mut MinHeapNode, b: *mut MinHeapNode) {
let mut t: MinHeapNode = MinHeapNode {
data: (*a).data,
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ impl Node {
self.next = next;
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Node {}
pub unsafe fn Find_0(mut head: *mut Node, mut idx: i32) -> *mut Node {
let mut curr: *mut Node = head;
let mut i: i32 = 0;
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/new_bst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub struct node_t {
pub right: *mut node_t,
pub value: i32,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for node_t {}
pub unsafe fn find_0(mut node: *mut node_t, mut value: i32) -> *mut node_t {
if ((value) < ((*node).value)) && (!(((*node).left).is_null())) {
return (unsafe {
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/push_emplace_back.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub struct Writer {
pub output: *mut Vec<Chunk>,
pub chunk: Chunk,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Writer {}
#[repr(C)]
#[derive(Clone, Default)]
pub struct JPEGData {
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/out/unsafe/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ impl Default for Pair {
}
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Pair {}
pub unsafe fn zero_0() -> i32 {
return 0;
}
Expand Down
44 changes: 44 additions & 0 deletions tests/unit/out/unsafe/send_sync_in_statics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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;
#[repr(C)]
#[derive(Copy, Clone, Default)]
pub struct Entry {
pub name: *const u8,
pub p: *mut i32,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for Entry {}
pub static single_entry: Entry = Entry {
name: b"alone\0".as_ptr(),
p: std::ptr::null_mut(),
};
pub static entries: [Entry; 2] = [
Entry {
name: b"first\0".as_ptr(),
p: std::ptr::null_mut(),
},
Entry {
name: b"second\0".as_ptr(),
p: std::ptr::null_mut(),
},
];
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
}
}
unsafe fn main_0() -> i32 {
assert!((single_entry.p).is_null());
let mut i: i32 = 0;
'loop_: while ((i) < (2)) {
assert!((entries[(i) as usize].p).is_null());
i.prefix_inc();
}
return 0;
}
4 changes: 4 additions & 0 deletions tests/unit/out/unsafe/union_field_alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ impl Default for node_anon_0 {
unsafe { std::mem::zeroed() }
}
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for node_anon_0 {}
#[repr(C)]
#[derive(Copy, Clone, Default)]
pub struct node {
pub next: *mut node,
pub x: node_anon_0,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for node {}
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
Expand Down
6 changes: 5 additions & 1 deletion tests/unit/out/unsafe/union_pointer_pun_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub struct node_b {
pub data: *mut ::libc::c_void,
pub next: *mut node_b,
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for node_b {}
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
Expand All @@ -34,7 +36,9 @@ unsafe fn main_0() -> i32 {
fn default() -> Self {
unsafe { std::mem::zeroed() }
}
};
}
// SAFETY: preserves unsafe C semantics; thread-safety is not enforced
unsafe impl Sync for anon_0 {};
let mut ptr: anon_0 = <anon_0>::default();
ptr.to_a = (&mut a as *mut node_a);
let mut out: *mut node_b = ptr.to_b;
Expand Down
Loading
Loading