tag | 93ffd6e9129c9daa9febbb9fd6623b8a940543e5 | |
---|---|---|
tagger | The Android Open Source Project <initial-contribution@android.com> | Mon Mar 13 10:56:02 2023 -0700 |
object | 74b42a9432b4335dafff9f6d1a76d6a6176882be |
Android 13.0.0 release 35
commit | 74b42a9432b4335dafff9f6d1a76d6a6176882be | [log] [tgz] |
---|---|---|
author | Joel Galenson <jgalenson@google.com> | Wed Dec 15 18:07:03 2021 +0000 |
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | Wed Dec 15 18:07:03 2021 +0000 |
tree | 5ba8f4e7cb27e5079549df0c552ceda186a0f538 | |
parent | bb26f7ec81e04b4d53225c2f3b112dab9bee56c5 [diff] | |
parent | f228529625f44ee32449076385bb411213ba28fa [diff] |
Merge "Refresh Android.bp, cargo2android.json, TEST_MAPPING." am: 0b0cd5de9e am: ec034b50da am: 51c06f7f8f am: f228529625 Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/no-panic/+/1912395 Change-Id: I4a9eab59a1aa8b7da72d04eba202f7b951ed0ca8
A Rust attribute macro to require that the compiler prove a function can't ever panic.
[dependencies] no-panic = "0.1"
use no_panic::no_panic; #[no_panic] fn demo(s: &str) -> &str { &s[1..] } fn main() { println!("{}", demo("input string")); }
If the function does panic (or the compiler fails to prove that the function cannot panic), the program fails to compile with a linker error that identifies the function name. Let's trigger that by passing a string that cannot be sliced at the first byte:
fn main() { println!("{}", demo("\u{1f980}input string")); }
Compiling no-panic-demo v0.0.1 error: linking with `cc` failed: exit code: 1 | = note: /no-panic-demo/target/release/deps/no_panic_demo-7170785b672ae322.no_p anic_demo1-cba7f4b666ccdbcbbf02b7348e5df1b2.rs.rcgu.o: In function `_$LT$no_pani c_demo..demo..__NoPanic$u20$as$u20$core..ops..drop..Drop$GT$::drop::h72f8f423002 b8d9f': no_panic_demo1-cba7f4b666ccdbcbbf02b7348e5df1b2.rs:(.text._ZN72_$LT$no _panic_demo..demo..__NoPanic$u20$as$u20$core..ops..drop..Drop$GT$4drop17h72f8f42 3002b8d9fE+0x2): undefined reference to ` ERROR[no-panic]: detected panic in function `demo` ' collect2: error: ld returned 1 exit status
The error is not stellar but notice the ERROR[no-panic] part at the end that provides the name of the offending function.
Compiler support: requires rustc 1.31+
Functions that require some amount of optimization to prove that they do not panic may no longer compile in debug mode after being marked #[no_panic]
.
Panic detection happens at link time across the entire dependency graph, so any Cargo commands that do not invoke a linker will not trigger panic detection. This includes cargo build
of library crates and cargo check
of binary and library crates.
The attribute is useless in code built with panic = "abort"
.
If you find that code requires optimization to pass #[no_panic]
, either make no-panic an optional dependency that you only enable in release builds, or add a section like the following to Cargo.toml to enable very basic optimization in debug builds.
[profile.dev] opt-level = 1
If the code that you need to prove isn't panicking makes function calls to non-generic non-inline functions from a different crate, you may need thin LTO enabled for the linker to deduce those do not panic.
[profile.release] lto = "thin"
If you want no_panic to just assume that some function you call doesn't panic, and get Undefined Behavior if it does at runtime, see dtolnay/no-panic#16; try wrapping that call in an unsafe extern "C"
wrapper.
The linker error technique is based on Kixunil's crate dont_panic
. Check out that crate for other convenient ways to require absence of panics.