Skip to main content

relibc/header/assert/
mod.rs

1//! `assert.h` implementation.
2//!
3//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/assert.h.html>.
4
5use crate::{
6    c_str::CStr,
7    platform::types::{c_char, c_int},
8};
9
10/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/assert.html>.
11///
12/// Writes information about the function that failed to `stderr` and calls
13/// `abort()`.
14///
15/// # Implementation
16/// `assert()` is defined as a C macro in cbindgen that checks for `NDEBUG`
17/// and if not found gets forwarded to this function call.
18///
19/// # Safety
20/// `func`, `file` and `cond` are guaranteed to be non-empty and valid.
21#[unsafe(no_mangle)]
22pub unsafe extern "C" fn __assert_fail(
23    func: *const c_char,
24    file: *const c_char,
25    line: c_int,
26    cond: *const c_char,
27) -> ! {
28    // SAFETY: `func` corresponds to the identifier `__func__` which is
29    // guaranteed to be non-empty and valid.
30    let func = unsafe { CStr::from_ptr(func) }.to_string_lossy();
31    // SAFETY: `file` corresponds to the macro `__FILE__` which is guaranteed
32    // to be non-empty and valid.
33    let file = unsafe { CStr::from_ptr(file) }.to_string_lossy();
34    // SAFETY: `cond` corresponds to the condition being asserted and is
35    // guaranteed to be non-empty and valid.
36    let cond = unsafe { CStr::from_ptr(cond) }.to_string_lossy();
37
38    eprintln!("{}: {}:{}: Assertion `{}` failed.", func, file, line, cond);
39
40    core::intrinsics::abort();
41}