Skip to content

Commit 99ec77f

Browse files
committed
unsafe attribute and api.rs
Clippy gives teh `not_unsafe_ptr_arg_deref` lint warning if a function dereferences a raw pointer but is not labelled as `unsafe`. We used to suppress this warning was because labelling a function `unsafe` automatically grants it rights to use any unsafe operation inside the function. I deemed that a greater danger because we then won't be able to identify real unsafe sections within an `unsafe` function. We now set `#![warn(unsafe_op_in_unsafe_fn)]` for the whole lib. It makes it necessary to use the `unsafe { ... }` block even within `unsafe` functions. We now explicitly label functions as `unsafe` if they deference raw pointers. But we set `#![allow(clippy::missing_safety_doc)]` on the `api.rs` module because the reason for functions to be unsafe in that module is clearly because they are used by C with raw pointers.
1 parent 8bf025e commit 99ec77f

File tree

3 files changed

+30
-21
lines changed

3 files changed

+30
-21
lines changed

mmtk/src/abi.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ impl GCThreadTLS {
252252
/// Has undefined behavior if `ptr` is invalid.
253253
pub unsafe fn check_cast(ptr: *mut GCThreadTLS) -> &'static mut GCThreadTLS {
254254
assert!(!ptr.is_null());
255-
let result = &mut *ptr;
255+
let result = unsafe { &mut *ptr };
256256
debug_assert!({
257257
let kind = result.kind;
258258
kind == GC_THREAD_KIND_WORKER
@@ -267,7 +267,7 @@ impl GCThreadTLS {
267267
/// Has undefined behavior if `ptr` is invalid.
268268
pub unsafe fn from_vwt_check(vwt: VMWorkerThread) -> &'static mut GCThreadTLS {
269269
let ptr = Self::from_vwt(vwt);
270-
Self::check_cast(ptr)
270+
unsafe { Self::check_cast(ptr) }
271271
}
272272

273273
#[allow(clippy::not_unsafe_ptr_arg_deref)] // `transmute` does not dereference pointer
@@ -283,7 +283,7 @@ impl GCThreadTLS {
283283
/// Has undefined behavior if the pointer held in C-level TLS is invalid.
284284
pub unsafe fn from_upcall_check() -> &'static mut GCThreadTLS {
285285
let ptr = (upcalls().get_gc_thread_tls)();
286-
Self::check_cast(ptr)
286+
unsafe { Self::check_cast(ptr) }
287287
}
288288

289289
pub fn worker<'w>(&mut self) -> &'w mut GCWorker<Ruby> {
@@ -314,7 +314,7 @@ impl RawVecOfObjRef {
314314
///
315315
/// This function turns raw pointer into a Vec without check.
316316
pub unsafe fn into_vec(self) -> Vec<ObjectReference> {
317-
Vec::from_raw_parts(self.ptr, self.len, self.capa)
317+
unsafe { Vec::from_raw_parts(self.ptr, self.len, self.capa) }
318318
}
319319
}
320320

mmtk/src/api.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
// All functions here are extern function. There is no point for marking them as unsafe.
2-
#![allow(clippy::not_unsafe_ptr_arg_deref)]
1+
// Functions in this module are unsafe for one reason:
2+
// They are called by C functions and they need to pass raw pointers to Rust.
3+
#![allow(clippy::missing_safety_doc)]
34

45
use std::ffi::CStr;
56
use std::sync::atomic::Ordering;
@@ -46,14 +47,14 @@ pub extern "C" fn mmtk_builder_default() -> *mut MMTKBuilder {
4647
/// Let the MMTKBuilder read options from environment variables,
4748
/// such as `MMTK_THREADS`.
4849
#[no_mangle]
49-
pub extern "C" fn mmtk_builder_read_env_var_settings(builder: *mut MMTKBuilder) {
50+
pub unsafe extern "C" fn mmtk_builder_read_env_var_settings(builder: *mut MMTKBuilder) {
5051
let builder = unsafe { &mut *builder };
5152
builder.options.read_env_var_settings();
5253
}
5354

5455
/// Set the GC trigger to dynamically adjust heap size.
5556
#[no_mangle]
56-
pub extern "C" fn mmtk_builder_set_dynamic_heap_size(
57+
pub unsafe extern "C" fn mmtk_builder_set_dynamic_heap_size(
5758
builder: *mut MMTKBuilder,
5859
low: usize,
5960
high: usize,
@@ -67,7 +68,10 @@ pub extern "C" fn mmtk_builder_set_dynamic_heap_size(
6768

6869
/// Set the GC trigger to use a fixed heap size.
6970
#[no_mangle]
70-
pub extern "C" fn mmtk_builder_set_fixed_heap_size(builder: *mut MMTKBuilder, heap_size: usize) {
71+
pub unsafe extern "C" fn mmtk_builder_set_fixed_heap_size(
72+
builder: *mut MMTKBuilder,
73+
heap_size: usize,
74+
) {
7175
let builder = unsafe { &mut *builder };
7276
builder
7377
.options
@@ -78,7 +82,10 @@ pub extern "C" fn mmtk_builder_set_fixed_heap_size(builder: *mut MMTKBuilder, he
7882
/// Set the plan. `plan_name` is a case-sensitive C-style ('\0'-terminated) string matching
7983
/// one of the cases of `enum PlanSelector`.
8084
#[no_mangle]
81-
pub extern "C" fn mmtk_builder_set_plan(builder: *mut MMTKBuilder, plan_name: *const libc::c_char) {
85+
pub unsafe extern "C" fn mmtk_builder_set_plan(
86+
builder: *mut MMTKBuilder,
87+
plan_name: *const libc::c_char,
88+
) {
8289
let builder = unsafe { &mut *builder };
8390
let plan_name_cstr = unsafe { CStr::from_ptr(plan_name) };
8491
let plan_name_str = plan_name_cstr.to_str().unwrap();
@@ -88,21 +95,21 @@ pub extern "C" fn mmtk_builder_set_plan(builder: *mut MMTKBuilder, plan_name: *c
8895

8996
/// Query if the selected plan is MarkSweep.
9097
#[no_mangle]
91-
pub extern "C" fn mmtk_builder_is_mark_sweep(builder: *mut MMTKBuilder) -> bool {
98+
pub unsafe extern "C" fn mmtk_builder_is_mark_sweep(builder: *mut MMTKBuilder) -> bool {
9299
let builder = unsafe { &mut *builder };
93100
matches!(*builder.options.plan, PlanSelector::MarkSweep)
94101
}
95102

96103
/// Query if the selected plan is Immix.
97104
#[no_mangle]
98-
pub extern "C" fn mmtk_builder_is_immix(builder: *mut MMTKBuilder) -> bool {
105+
pub unsafe extern "C" fn mmtk_builder_is_immix(builder: *mut MMTKBuilder) -> bool {
99106
let builder = unsafe { &mut *builder };
100107
matches!(*builder.options.plan, PlanSelector::Immix)
101108
}
102109

103110
/// Query if the selected plan is StickyImmix.
104111
#[no_mangle]
105-
pub extern "C" fn mmtk_builder_is_sticky_immix(builder: *mut MMTKBuilder) -> bool {
112+
pub unsafe extern "C" fn mmtk_builder_is_sticky_immix(builder: *mut MMTKBuilder) -> bool {
106113
let builder = unsafe { &mut *builder };
107114
matches!(*builder.options.plan, PlanSelector::StickyImmix)
108115
}
@@ -114,7 +121,7 @@ pub extern "C" fn mmtk_builder_is_sticky_immix(builder: *mut MMTKBuilder) -> boo
114121
/// the MMTk instance.
115122
/// - `upcalls` points to the struct that contains upcalls. It is allocated in C as static.
116123
#[no_mangle]
117-
pub extern "C" fn mmtk_init_binding(
124+
pub unsafe extern "C" fn mmtk_init_binding(
118125
builder: *mut MMTKBuilder,
119126
binding_options: *const RubyBindingOptions,
120127
upcalls: *const abi::RubyUpcalls,
@@ -139,13 +146,13 @@ pub extern "C" fn mmtk_bind_mutator(tls: VMMutatorThread) -> *mut RubyMutator {
139146
}
140147

141148
#[no_mangle]
142-
pub extern "C" fn mmtk_destroy_mutator(mutator: *mut RubyMutator) {
149+
pub unsafe extern "C" fn mmtk_destroy_mutator(mutator: *mut RubyMutator) {
143150
let mut boxed_mutator = unsafe { Box::from_raw(mutator) };
144151
memory_manager::destroy_mutator(boxed_mutator.as_mut())
145152
}
146153

147154
#[no_mangle]
148-
pub extern "C" fn mmtk_alloc(
155+
pub unsafe extern "C" fn mmtk_alloc(
149156
mutator: *mut RubyMutator,
150157
size: usize,
151158
align: usize,
@@ -163,7 +170,7 @@ pub extern "C" fn mmtk_alloc(
163170
}
164171

165172
#[no_mangle]
166-
pub extern "C" fn mmtk_post_alloc(
173+
pub unsafe extern "C" fn mmtk_post_alloc(
167174
mutator: *mut RubyMutator,
168175
refer: ObjectReference,
169176
bytes: usize,
@@ -285,7 +292,7 @@ pub extern "C" fn mmtk_add_obj_free_candidate(object: ObjectReference) {
285292
}
286293

287294
#[no_mangle]
288-
pub extern "C" fn mmtk_add_obj_free_candidates(objects: *const ObjectReference, len: usize) {
295+
pub unsafe extern "C" fn mmtk_add_obj_free_candidates(objects: *const ObjectReference, len: usize) {
289296
let objects_slice = unsafe { std::slice::from_raw_parts(objects, len) };
290297
binding().weak_proc.add_obj_free_candidates(objects_slice)
291298
}
@@ -307,7 +314,7 @@ pub extern "C" fn mmtk_register_ppp(object: ObjectReference) {
307314
}
308315

309316
#[no_mangle]
310-
pub extern "C" fn mmtk_register_ppps(objects: *const ObjectReference, len: usize) {
317+
pub unsafe extern "C" fn mmtk_register_ppps(objects: *const ObjectReference, len: usize) {
311318
let objects_slice = unsafe { std::slice::from_raw_parts(objects, len) };
312319
crate::binding().ppp_registry.register_many(objects_slice)
313320
}
@@ -371,7 +378,7 @@ pub extern "C" fn mmtk_is_object_wb_unprotected(object: ObjectReference) -> bool
371378
}
372379

373380
#[no_mangle]
374-
pub extern "C" fn mmtk_object_reference_write_post(
381+
pub unsafe extern "C" fn mmtk_object_reference_write_post(
375382
mutator: *mut RubyMutator,
376383
object: ObjectReference,
377384
) {
@@ -398,7 +405,7 @@ pub extern "C" fn mmtk_enumerate_objects(
398405
}
399406

400407
#[no_mangle]
401-
pub extern "C" fn mmtk_hidden_header_is_sane(hidden_header: *const HiddenHeader) -> bool {
408+
pub unsafe extern "C" fn mmtk_hidden_header_is_sane(hidden_header: *const HiddenHeader) -> bool {
402409
let hidden_header = unsafe { &*hidden_header };
403410
hidden_header.is_sane()
404411
}

mmtk/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![warn(unsafe_op_in_unsafe_fn)]
2+
13
extern crate libc;
24
extern crate mmtk;
35
#[macro_use]

0 commit comments

Comments
 (0)