Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some basic docs for unsafe attrs #1539

Merged
merged 6 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions src/abi.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,27 @@ item's name.
Additionally, the item will be publicly exported from the produced library or
object file, similar to the [`used` attribute](#the-used-attribute).

This attribute is unsafe as an unmangled symbol may collide with another symbol
with the same name (or with a well-known symbol), leading to undefined behavior.

```rust
#[unsafe(no_mangle)]
extern "C" fn foo() {}
```

## The `link_section` attribute

The *`link_section` attribute* specifies the section of the object file that a
[function] or [static]'s content will be placed into. It uses the
[_MetaNameValueStr_] syntax to specify the section name.

This attribute is unsafe as it allows users to place data and code into sections
of memory not expecting them, such as mutable data into read-only areas.

<!-- no_run: don't link. The format of the section name is platform-specific. -->
```rust,no_run
#[no_mangle]
#[link_section = ".example_section"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".example_section")]
pub static VAR1: u32 = 1;
```

Expand All @@ -85,8 +96,12 @@ The *`export_name` attribute* specifies the name of the symbol that will be
exported on a [function] or [static]. It uses the [_MetaNameValueStr_] syntax
to specify the symbol name.

This attribute is unsafe as a symbol with a custom name may collide with another
symbol with the same name (or with a well-known symbol), leading to undefined
behavior.

```rust
#[export_name = "exported_symbol_name"]
#[unsafe(export_name = "exported_symbol_name")]
pub fn name_in_rust() { }
```

Expand Down
14 changes: 13 additions & 1 deletion src/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
> &nbsp;&nbsp; `#` `[` _Attr_ `]`
>
> _Attr_ :\
> &nbsp;&nbsp; [_SimplePath_] _AttrInput_<sup>?</sup>
> &nbsp;&nbsp; &nbsp;&nbsp; [_SimplePath_] _AttrInput_<sup>?</sup>\
> &nbsp;&nbsp; | `unsafe` `(` [_SimplePath_] _AttrInput_<sup>?</sup> `)`
>
> _AttrInput_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; [_DelimTokenTree_]\
Expand All @@ -29,6 +30,17 @@ Attributes other than macro attributes also allow the input to be an equals
sign (`=`) followed by an expression. See the [meta item
syntax](#meta-item-attribute-syntax) below for more details.

An attribute may be unsafe to apply. To avoid undefined behavior when using
these attributes, certain obligations that cannot be checked by the compiler
must be met. To assert these have been, the attribute is wrapped in
`unsafe(..)`, e.g. `#[unsafe(no_mangle)]`.

The following attributes are unsafe:

* [`export_name`]
* [`link_section`]
* [`no_mangle`]

Attributes can be classified into the following kinds:

* [Built-in attributes]
Expand Down
10 changes: 8 additions & 2 deletions src/unsafe-keyword.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# The `unsafe` keyword

The `unsafe` keyword can occur in several different contexts:
unsafe functions (`unsafe fn`), unsafe blocks (`unsafe {}`), unsafe traits (`unsafe trait`), unsafe trait implementations (`unsafe impl`), and unsafe external blocks (`unsafe extern`).
unsafe functions (`unsafe fn`), unsafe blocks (`unsafe {}`), unsafe traits (`unsafe trait`), unsafe trait implementations (`unsafe impl`), unsafe external blocks (`unsafe extern`), and unsafe attributes (`#[unsafe(attr)]`).
It plays several different roles, depending on where it is used and whether the `unsafe_op_in_unsafe_fn` lint is enabled:
- it is used to mark code that *defines* extra safety conditions (`unsafe fn`, `unsafe trait`)
- it is used to mark code that needs to *satisfy* extra safety conditions (`unsafe {}`, `unsafe impl`, `unsafe fn` without [`unsafe_op_in_unsafe_fn`], `unsafe extern`)
- it is used to mark code that needs to *satisfy* extra safety conditions (`unsafe {}`, `unsafe impl`, `unsafe fn` without [`unsafe_op_in_unsafe_fn`], `unsafe extern`, `#[unsafe(attr)]`)

The following discusses each of these cases.
See the [keyword documentation][keyword] for some illustrative examples.
Expand Down Expand Up @@ -62,3 +62,9 @@ Unsafe trait implementations are the logical dual to unsafe traits: where unsafe
The programmer who declares an [external block] must assure that the signatures of the items contained within are correct. Failing to do so may lead to undefined behavior. That this obligation has been met is indicated by writing `unsafe extern`.

[external block]: items/external-blocks.md

## Unsafe attributes (`#[unsafe(attr)]`)

An [unsafe attribute] is one that has extra safety conditions that must be upheld when using the attribute. The compiler cannot check whether these conditions have been upheld. To assert that they have been, these attributes must be wrapped in `unsafe(..)`, e.g. `#[unsafe(no_mangle)]`.

[unsafe attribute]: attributes.md
2 changes: 2 additions & 0 deletions src/unsafety.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ Rust:
- Calling an unsafe function (including an intrinsic or foreign function).
- Implementing an [unsafe trait].
- Declaring an [`extern`] block.
- Applying an [unsafe attribute] to an item.

[`extern`]: items/external-blocks.md
[`union`]: items/unions.md
[mutable]: items/static-items.md#mutable-statics
[external]: items/external-blocks.md
[raw pointer]: types/pointer.md
[unsafe trait]: items/traits.md#unsafe-traits
[unsafe attribute]: attributes.md