Skip to content

Lint against #[no_mangle] for non-repr(C) pub statics #11219

Open
@ojeda

Description

@ojeda

What it does

The lint should lint against a #[no_mangle] pub static which has a type which is not repr(C) (or that has no explicit repr(Rust) set).

This would be similar to no_mangle_with_rust_abi from #10347, but for pub statics.

Advantage

Avoids potential subtle mistakes and UB in programs that mix Rust and other languages like C: one cannot predict the layout of repr(Rust) types and thus an exported static marked with #[no_mangle] has a high chance of being a mistake.

Drawbacks

No response

Example

pub struct S(u8, u16);

#[no_mangle]
pub static X: S = S(0xFF, 0xFFFF);

Should be written as:

#[repr(C)]
pub struct S(u8, u16);

#[no_mangle]
pub static X: S = S(0xFF, 0xFFFF);

Otherwise, a C program with manually written bindings (e.g. projects not using cbindgen, which in this case would generate an incomplete type) trying to access X will break sooner or later, potentially silently (using -Zrandomize-layout would increase the chances of the issue being spotted, though), e.g.

#include <assert.h>
#include <stdint.h>

struct S {
    uint8_t a;
    uint16_t b;
};

extern const struct S X;

int main(void) {
    assert(X.a == 0xFF);
    assert(X.b == 0xFFFF);
    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions