W1010
W1010 — Anunsafeblock with nothing inside it that needsunsafe.
What the compiler reports
Warning[W1010] at {{.*}}warning_for_unsafe_with_nothing_unsafe.vx:52:11: this `unsafe` block holds nothing that needs `unsafe`
Warning[W1010] at {{.*}}warning_for_unsafe_with_nothing_unsafe.vx:60:12: this `unsafe` block is inside another one
The fragments the test suite holds the compiler to. An ellipsis marks text the test does not constrain; the emitted message also carries a source location.
A program that triggers it
//
// Part of the Vx Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//
// An `unsafe` block with nothing inside that needs `unsafe` gets W1010, and so does one inside
// another `unsafe` block. Reading through a raw pointer, calling an `unsafe fn` or a C function,
// and turning an integer into a pointer all need `unsafe`, so those blocks get no warning. So does
// a call whose pointer `requires` the compiler cannot prove, which the block lets it trust.
// Neither does a block that declares a variable (Vx has no plain `{ .. }` block). `vec![..]`
// becomes an `unsafe` block the compiler writes, which never warns or counts as an outer block.
import std::vec;
import core::ops;
extern {
fn c_abs(x: i32) -> i32;
}
unsafe fn read(p : *mut i32) -> i32 {
let v = unsafe { *p };
return v;
}
struct Cell {
v : i32,
}
impl Cell {
unsafe fn make(p : *mut i32) -> Cell {
let v = unsafe { *p };
return Cell {
v : v
};
}
}
fn main() -> i32 {
let mut x : i32 = 1;
let mut y : i32 = 2;
let p : *mut i32 = &mut y;
let a = unsafe { x + 1 };
let b = unsafe { *p };
let c = unsafe { read(p) };
let d = unsafe { c_abs(0 - 3) };
let _q = unsafe { 0 as *mut i32 };
// The second call finds the function the first call made, a different path in the checker.
let first = unsafe { Cell::make(p) };
let second = unsafe { Cell::make(p) };
unsafe { unsafe { x = *p; } }
unsafe { let x = 5; print(x); }
let pair = vec![b, unsafe { *p }];
print(pair.len());
let e = unsafe { first_of(p as *const i32, 2i64) };
return a + b + c + d + e + first.v + second.v;
}
fn first_of(q : *const i32, n : i64) -> i32
requires valid(q, n)
{
return unsafe { q[0] };
}
From tests/frontend/pass/warning_for_unsafe_with_nothing_unsafe.vx, which asserts this diagnostic on every commit.