Skip to content

Inline assembly lifetime extension / statement #1976

@VorpalBlade

Description

@VorpalBlade

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-asmArea: inline assembly

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions