tag_safe
This is a linter designed originally for use with a kernel, where functions need to be marked as "IRQ safe" (meaning they are safe to call within an IRQ handler, and handle the case where they may interrupt themselves).
Detailed
If a function is annotated with #[req_safe(ident)]
(where ident
can be anything, and defines the type of safety)
this linter will check that all functions called by that function are either annotated with the same annotation or
#[is_safe(ident)]
, OR they do not call functions with the reverse #[is_unsafe(ident)]
annotation.
By default this lint is a warning, if you would like to make it a hard error add #[deny(not_tagged_safe)]
Extern crate imports can be annotated with #[tagged_safe(tag="path/to/list.txt")
to load a list of tagged methods
from an external file. The path is relative to where rustc was invoked (currently), and contains a default tag (true
or false) followed by a newline separated list of methods.
Example
This file annotates all functions in libstd as safe, except for std::io::_print
(which is the backend for print!
)
true
std::io::_print
Usage
Below is an example of using this flag to prevent accidentally using an IRQ-unsafe method in an IRQ handler.
(Assume the lock used by acquire_irq_spinlock
is different to the one acquired by acquire_non_irq_spinlock
)
/// RAII primitive spinlock
;
/// Handle to said spinlock
;
/// RAII IRQ hold
;
/// Spinlock that also disables IRQs
;
static S_NON_IRQ_SPINLOCK: Spinlock = Spinlock;
static S_IRQ_SPINLOCK: IrqSpinlock = IrqSpinlock;
// Make the lint an error
// Require this method be IRQ safe
// This method handles IRQ safety internally, and hence makes
// this lint allowable.
// Stop IRQs from firing until the returned value is dropped
// Not safe to call in an IRQ without protection (as that can lead to a
// uniprocessor deadlock)