Skip to content

LLVM nocapture attribute is used incorrectly #137668

Description

@tmiasko

The implementation of indirect_pass_mode contains following code:

        // For non-immediate arguments the callee gets its own copy of
        // the value on the stack, so there are no aliases. It's also
        // program-invisible so can't possibly capture
        attrs
            .set(ArgAttribute::NoAlias)
            .set(ArgAttribute::NoCapture)
            .set(ArgAttribute::NonNull)
            .set(ArgAttribute::NoUndef);

The claim that a callee can't possibly capture the argument is incorrect. The callee can obtain the address of the parameter and use it in arbitrary way. Consider the following example. In the call to f, b is an address of a static S, whose memory should be disjoint from parameter a. Consequently f should return false:

static S: [u32; 64]  = [0; 64];

#[inline(never)]
pub fn f(a: [u32; 64], b: usize) -> bool {
    &a as *const _ as usize == b
}

fn main() {
    assert!(!f(S, &S as *const _ as usize));
}
$ rustc a.rs -Copt-level=0 && ./a
$ rustc a.rs -Copt-level=1 && ./a

thread 'main' panicked at a.rs:9:5:
assertion failed: !f(S, &S as *const _ as usize)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-opsemRelevant to the opsem team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions