G.UNS.PTR.02 禁止将不可变指针手工转换为可变指针

【级别】 要求

【描述】

因为将不可变指针手工转换为可变指针可能会引发未定义行为。通常有这种需求,合法的手段是使用 UnsafeCell<T>

【 反例】


#![allow(unused)]
fn main() {
fn x(r: &i32) {
    unsafe {
        *(r as *const _ as *mut _) += 1; // 不符合
    }
}
}

【正例】


#![allow(unused)]
fn main() {
use std::cell::UnsafeCell;

// 符合
fn x(r: &UnsafeCell<i32>) {
   unsafe {
       *r.get() += 1; 
   }
}
}

【例外】

也有例外情况,当明确知道这种转换会出现什么风险的时候,可以使用,或者在找到合适的解决办法之前 作为一种临时方案,但要加上注释。


#![allow(unused)]
fn main() {
// https://docs.rs/crate/solana-runtime/1.7.11/source/src/append_vec.rs
#[allow(clippy::cast_ref_to_mut)]
fn set_data_len_unsafe(&self, new_data_len: u64) {
    // UNSAFE: cast away & (= const ref) to &mut to force to mutate append-only (=read-only) AppendVec
    unsafe {
        *(&self.meta.data_len as *const u64 as *mut u64) = new_data_len;
    }
}

// https://docs.rs/crate/mmtk/0.6.0/source/src/policy/space.rs
// This is a temporary solution to allow unsafe mut reference. We do not want several occurrence
// of the same unsafe code.
// FIXME: We need a safe implementation.
#[allow(clippy::cast_ref_to_mut)]
#[allow(clippy::mut_from_ref)]
unsafe fn mut_self(&self) -> &mut Self {
    &mut *(self as *const _ as *mut _)
}
}

【Lint 检测】

lint nameClippy 可检测Rustc 可检测Lint Grouplevel
cast_ref_to_mutyesnocorrectnessdeny