-
Notifications
You must be signed in to change notification settings - Fork 551
Description
This began as this URLO thread: https://users.rust-lang.org/t/end-of-statement-lifetime-in-inline-assembly-blocks/133373
I have have code like:
pub fn macro_generated_function(location: &std::panic::Location) {
unsafe {
std::arch::asm!(
"... {0} ...",
in (reg) (std::ffi::CString::new(location.file()).unwrap().as_ptr()) as isize,
options(readonly, preserves_flags, nostack, att_syntax)
)
};
}
This results in a warning:
warning: a dangling pointer will be produced because the temporary `CString` will be dropped
--> src/lib.rs:498:76
|
498 | in (reg) (std::ffi::CString::new(location.file()).unwrap().as_ptr()) as isize,
| ------------------------------------------------ ^^^^^^ this pointer will immediately be invalid
| |
| this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
|
= note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
= help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr`
= help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
= note: `#[warn(dangling_pointers_from_temporaries)]` on by default
However, it isn't clear from the reference what the "statement" is when it comes to a macro like asm!
. Is the statement the whole asm!() (in which case it is fine for my use case), or does the lifetime end before the assembly code is executed? Wouldn't lifetime extension extend this lifetime to the end of the asm!()
?
"Normal" macros can after all expand to multiple statements, and it is unclear what the semantics are around a built in macro like asm!
. The code does work in practise (the destructor appears to be called after the inline assembly, see godbolt) but I would like this to be properly documented (presumably at https://doc.rust-lang.org/reference/inline-assembly.html)