Inline assembly lifetime extension / statement

Open
#1,976 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
38/100
Issue type
Documentation
Clarity
Mostly clear
Activity status
Stale
Tech stack
rust
Domain
documentation

Research direction

Start with the inline-assembly section of the Rust Reference, then review the linked URLO discussion and Godbolt example. Determine how statement boundaries and temporary lifetime extension apply to asm! operands and identify the precise behavior that needs documenting. Done means the Reference clearly explains when the temporary is dropped relative to the assembly execution.

Written by the indexing model from the issue text.

Description

A-asm

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)

Dominant language
Rust
Stars
1.6k
Forks
618
Avg merge
5h 48m
Merged PRs (30d)
3

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from rust-lang/reference

All issues in rust-lang/reference

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.