Skip to content

Commit 135bdee

Browse files
authored
Merge pull request #1539 from carbotaniuman/add-unsafe-attr-docs
Add some basic docs for unsafe attrs
2 parents ecf7600 + 73c11ac commit 135bdee

File tree

4 files changed

+41
-6
lines changed

4 files changed

+41
-6
lines changed

src/abi.md

+18-3
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,27 @@ item's name.
6666
Additionally, the item will be publicly exported from the produced library or
6767
object file, similar to the [`used` attribute](#the-used-attribute).
6868

69+
This attribute is unsafe as an unmangled symbol may collide with another symbol
70+
with the same name (or with a well-known symbol), leading to undefined behavior.
71+
72+
```rust
73+
#[unsafe(no_mangle)]
74+
extern "C" fn foo() {}
75+
```
76+
6977
## The `link_section` attribute
7078

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

83+
This attribute is unsafe as it allows users to place data and code into sections
84+
of memory not expecting them, such as mutable data into read-only areas.
85+
7586
<!-- no_run: don't link. The format of the section name is platform-specific. -->
7687
```rust,no_run
77-
#[no_mangle]
78-
#[link_section = ".example_section"]
88+
#[unsafe(no_mangle)]
89+
#[unsafe(link_section = ".example_section")]
7990
pub static VAR1: u32 = 1;
8091
```
8192

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

99+
This attribute is unsafe as a symbol with a custom name may collide with another
100+
symbol with the same name (or with a well-known symbol), leading to undefined
101+
behavior.
102+
88103
```rust
89-
#[export_name = "exported_symbol_name"]
104+
#[unsafe(export_name = "exported_symbol_name")]
90105
pub fn name_in_rust() { }
91106
```
92107

src/attributes.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
> &nbsp;&nbsp; `#` `[` _Attr_ `]`
1010
>
1111
> _Attr_ :\
12-
> &nbsp;&nbsp; [_SimplePath_] _AttrInput_<sup>?</sup>
12+
> &nbsp;&nbsp; &nbsp;&nbsp; [_SimplePath_] _AttrInput_<sup>?</sup>\
13+
> &nbsp;&nbsp; | `unsafe` `(` [_SimplePath_] _AttrInput_<sup>?</sup> `)`
1314
>
1415
> _AttrInput_ :\
1516
> &nbsp;&nbsp; &nbsp;&nbsp; [_DelimTokenTree_]\
@@ -29,6 +30,17 @@ Attributes other than macro attributes also allow the input to be an equals
2930
sign (`=`) followed by an expression. See the [meta item
3031
syntax](#meta-item-attribute-syntax) below for more details.
3132

33+
An attribute may be unsafe to apply. To avoid undefined behavior when using
34+
these attributes, certain obligations that cannot be checked by the compiler
35+
must be met. To assert these have been, the attribute is wrapped in
36+
`unsafe(..)`, e.g. `#[unsafe(no_mangle)]`.
37+
38+
The following attributes are unsafe:
39+
40+
* [`export_name`]
41+
* [`link_section`]
42+
* [`no_mangle`]
43+
3244
Attributes can be classified into the following kinds:
3345

3446
* [Built-in attributes]

src/unsafe-keyword.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# The `unsafe` keyword
22

33
The `unsafe` keyword can occur in several different contexts:
4-
unsafe functions (`unsafe fn`), unsafe blocks (`unsafe {}`), unsafe traits (`unsafe trait`), unsafe trait implementations (`unsafe impl`), and unsafe external blocks (`unsafe extern`).
4+
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)]`).
55
It plays several different roles, depending on where it is used and whether the `unsafe_op_in_unsafe_fn` lint is enabled:
66
- it is used to mark code that *defines* extra safety conditions (`unsafe fn`, `unsafe trait`)
7-
- 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`)
7+
- 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)]`)
88

99
The following discusses each of these cases.
1010
See the [keyword documentation][keyword] for some illustrative examples.
@@ -62,3 +62,9 @@ Unsafe trait implementations are the logical dual to unsafe traits: where unsafe
6262
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`.
6363

6464
[external block]: items/external-blocks.md
65+
66+
## Unsafe attributes (`#[unsafe(attr)]`)
67+
68+
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)]`.
69+
70+
[unsafe attribute]: attributes.md

src/unsafety.md

+2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ Rust:
1212
- Calling an unsafe function (including an intrinsic or foreign function).
1313
- Implementing an [unsafe trait].
1414
- Declaring an [`extern`] block.
15+
- Applying an [unsafe attribute] to an item.
1516

1617
[`extern`]: items/external-blocks.md
1718
[`union`]: items/unions.md
1819
[mutable]: items/static-items.md#mutable-statics
1920
[external]: items/external-blocks.md
2021
[raw pointer]: types/pointer.md
2122
[unsafe trait]: items/traits.md#unsafe-traits
23+
[unsafe attribute]: attributes.md

0 commit comments

Comments
 (0)