Skip to content

Rollup of 7 pull requests #95827

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

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
39bff4b
don't report int/float ambiguity when we have previous errors
compiler-errors Apr 7, 2022
2f46de2
Add current_thread_unique_ptr() in std::sys_common.
m-ou-se Apr 6, 2022
619163e
Add futex-based ReentrantMutex on Linux.
m-ou-se Apr 6, 2022
d5e0eaf
Make current_thread_unique_ptr work during thread destruction.
m-ou-se Apr 6, 2022
6888fb1
Move current_thread_unique_ptr to the only module that uses it.
m-ou-se Apr 6, 2022
dc82718
Initialize thread local with const{}.
m-ou-se Apr 6, 2022
aeb01c3
Add debug asserts to futex ReentrantMutex impl.
m-ou-se Apr 6, 2022
0664b8a
Add #[deny(unsafe_op_in_unsafe_fn)] to thread_local!(const).
m-ou-se Apr 6, 2022
5974c18
[macro_metavar_expr] Add tests to ensure the feature requirement
c410-f3r Apr 7, 2022
d0cc986
check_doc_keyword: don't alloc string for emptiness check
klensy Apr 5, 2022
43d0497
Fix invalid array access in `beautify_doc_string`
GuillaumeGomez Apr 8, 2022
5e8bd9b
Add test for empty doc comments with a backline
GuillaumeGomez Apr 8, 2022
1040cab
WIP PROOF-OF-CONCEPT: Make the compiler complain about all int<->ptr …
Gankra Mar 21, 2022
98a4834
Split `fuzzy_provenance_casts` into lossy and fuzzy, feature gate and…
niluxv Apr 2, 2022
f6c7f10
Remove extra space before a where clause in the documentation
Urgau Apr 8, 2022
c5693d3
Rollup merge of #95599 - niluxv:strict-provenance-lint, r=michaelwoer…
Dylan-DPC Apr 8, 2022
b367ce8
Rollup merge of #95697 - klensy:no-strings, r=petrochenkov
Dylan-DPC Apr 8, 2022
66b3081
Rollup merge of #95727 - m-ou-se:futex-reentrantmutex, r=Amanieu
Dylan-DPC Apr 8, 2022
8b5a795
Rollup merge of #95751 - compiler-errors:ambig-int, r=jackh726
Dylan-DPC Apr 8, 2022
7328ae9
Rollup merge of #95764 - c410-f3r:metavar-test, r=petrochenkov
Dylan-DPC Apr 8, 2022
1a0aaee
Rollup merge of #95804 - GuillaumeGomez:empty-doc-comment-with-backli…
Dylan-DPC Apr 8, 2022
00c3d88
Rollup merge of #95813 - Urgau:rustdoc-where-clause-space, r=Guillaum…
Dylan-DPC Apr 8, 2022
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
Prev Previous commit
Next Next commit
Split fuzzy_provenance_casts into lossy and fuzzy, feature gate and…
… test it

* split `fuzzy_provenance_casts` into a ptr2int and a int2ptr lint
* feature gate both lints
* update documentation to be more realistic short term
* add tests for these lints
  • Loading branch information
niluxv committed Apr 8, 2022
commit 98a483423720bda1f51a22f01b378fa8e8e8b9a3
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,8 @@ declare_features! (
(active, static_nobundle, "1.16.0", Some(37403), None),
/// Allows attributes on expressions and non-item statements.
(active, stmt_expr_attributes, "1.6.0", Some(15701), None),
/// Allows lints part of the strict provenance effort.
(active, strict_provenance, "1.61.0", Some(95228), None),
/// Allows the use of `#[target_feature]` on safe functions.
(active, target_feature_11, "1.45.0", Some(69098), None),
/// Allows using `#[thread_local]` on `static` items.
Expand Down
88 changes: 72 additions & 16 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2654,33 +2654,88 @@ declare_lint! {
///
/// ### Example
///
/// ```rust
/// #![feature(strict_provenance)]
/// #![warn(fuzzy_provenance_casts)]
///
/// fn main() {
/// let my_ref = &0;
/// let my_addr = my_ref as usize;
/// let _dangling = 16_usize as *const u8;
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Casting a pointer to an integer or an integer to a pointer is a lossy operation,
/// because beyond just an *address* a pointer may be associated with a particular
/// *provenance* and *segment*. This information is required by both the compiler
/// and the hardware to correctly execute your code. If you need to do this kind
/// of operation, use ptr::addr and ptr::with_addr.
/// This lint is part of the strict provenance effort, see [issue #95228].
/// Casting an integer to a pointer is considered bad style, as a pointer
/// contains, besides the *address* also a *provenance*, indicating what
/// memory the pointer is allowed to read/write. Casting an integer, which
/// doesn't have provenance, to a pointer requires the compiler to assign
/// (guess) provenance. The compiler assigns "all exposed valid" (see the
/// docs of [`ptr::from_exposed_addr`] for more information about this
/// "exposing"). This penalizes the optimiser and is not well suited for
/// dynamic analysis/dynamic program verification (e.g. Miri or CHERI
/// platforms).
///
/// This is a [future-incompatible] lint to transition this to a hard error
/// in the future. See [issue #9999999] for more details.
/// It is much better to use [`ptr::with_addr`] instead to specify the
/// provenance you want. If using this function is not possible because the
/// code relies on exposed provenance then there is as an escape hatch
/// [`ptr::from_exposed_addr`].
///
/// [future-incompatible]: ../index.md#future-incompatible-lints
/// [issue #9999999]: https://github.com/rust-lang/rust/issues/9999999
/// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
/// [`ptr::with_addr`]: https://doc.rust-lang.org/core/ptr/fn.with_addr
/// [`ptr::from_exposed_addr`]: https://doc.rust-lang.org/core/ptr/fn.from_exposed_addr
pub FUZZY_PROVENANCE_CASTS,
Warn,
"A lossy pointer-integer integer cast is used",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #9999999 <https://github.com/rust-lang/rust/issues/9999999>",
};
Allow,
"a fuzzy integer to pointer cast is used",
@feature_gate = sym::strict_provenance;
}

declare_lint! {
/// The `lossy_provenance_casts` lint detects an `as` cast between a pointer
/// and an integer.
///
/// ### Example
///
/// ```rust
/// #![feature(strict_provenance)]
/// #![warn(lossy_provenance_casts)]
///
/// fn main() {
/// let x: u8 = 37;
/// let _addr: usize = &x as *const u8 as usize;
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// This lint is part of the strict provenance effort, see [issue #95228].
/// Casting a pointer to an integer is a lossy operation, because beyond
/// just an *address* a pointer may be associated with a particular
/// *provenance*. This information is used by the optimiser and for dynamic
/// analysis/dynamic program verification (e.g. Miri or CHERI platforms).
///
/// Since this cast is lossy, it is considered good style to use the
/// [`ptr::addr`] method instead, which has a similar effect, but doesn't
/// "expose" the pointer provenance. This improves optimisation potential.
/// See the docs of [`ptr::addr`] and [`ptr::expose_addr`] for more information
/// about exposing pointer provenance.
///
/// If your code can't comply with strict provenance and needs to expose
/// the provenance, then there is [`ptr::expose_addr`] as an escape hatch,
/// which preserves the behaviour of `as usize` casts while being explicit
/// about the semantics.
///
/// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
/// [`ptr::addr`]: https://doc.rust-lang.org/core/ptr/fn.addr
/// [`ptr::expose_addr`]: https://doc.rust-lang.org/core/ptr/fn.expose_addr
pub LOSSY_PROVENANCE_CASTS,
Allow,
"a lossy pointer to integer cast is used",
@feature_gate = sym::strict_provenance;
}

declare_lint! {
Expand Down Expand Up @@ -3137,6 +3192,7 @@ declare_lint_pass! {
INCOMPLETE_INCLUDE,
CENUM_IMPL_DROP_CAST,
FUZZY_PROVENANCE_CASTS,
LOSSY_PROVENANCE_CASTS,
CONST_EVALUATABLE_UNCHECKED,
INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
MUST_NOT_SUSPEND,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,7 @@ symbols! {
str_trim,
str_trim_end,
str_trim_start,
strict_provenance,
stringify,
stringify_macro,
struct_field_attributes,
Expand Down
61 changes: 42 additions & 19 deletions compiler/rustc_typeck/src/check/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,12 +809,12 @@ impl<'a, 'tcx> CastCheck<'tcx> {
(Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast

// ptr-addr-cast
(Ptr(m_expr), Int(_)) => {
self.fuzzy_provenance_ptr2int_lint(fcx, t_from);
(Ptr(m_expr), Int(t_c)) => {
self.lossy_provenance_ptr2int_lint(fcx, t_c);
self.check_ptr_addr_cast(fcx, m_expr)
}
(FnPtr, Int(_)) => {
self.fuzzy_provenance_ptr2int_lint(fcx, t_from);
// FIXME(#95489): there should eventually be a lint for these casts
Ok(CastKind::FnPtrAddrCast)
}
// addr-ptr-cast
Expand Down Expand Up @@ -945,7 +945,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
fcx: &FnCtxt<'a, 'tcx>,
m_cast: TypeAndMut<'tcx>,
) -> Result<CastKind, CastError> {
self.fuzzy_provenance_int2ptr_lint(fcx);
// ptr-addr cast. pointer must be thin.
match fcx.pointer_kind(m_cast.ty, self.span)? {
None => Err(CastError::UnknownCastPtrKind),
Expand Down Expand Up @@ -986,25 +985,36 @@ impl<'a, 'tcx> CastCheck<'tcx> {
}
}

fn fuzzy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_from: CastTy<'tcx>) {
fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) {
fcx.tcx.struct_span_lint_hir(
lint::builtin::FUZZY_PROVENANCE_CASTS,
lint::builtin::LOSSY_PROVENANCE_CASTS,
self.expr.hir_id,
self.span,
|err| {
let mut err = err.build(&format!(
"strict provenance disallows casting pointer `{}` to integer `{}`",
"under strict provenance it is considered bad style to cast pointer `{}` to integer `{}`",
self.expr_ty, self.cast_ty
));

if let CastTy::FnPtr = t_from {
err.help(
"use `(... as *const u8).addr()` to obtain \
the address of a function pointer",
let msg = "use `.addr()` to obtain the address of a pointer";
if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) {
let scalar_cast = match t_c {
ty::cast::IntTy::U(ty::UintTy::Usize) => String::new(),
_ => format!(" as {}", self.cast_ty),
};
err.span_suggestion(
self.span,
msg,
format!("({}).addr(){}", snippet, scalar_cast),
Applicability::MaybeIncorrect
);
} else {
err.help("use `.addr()` to obtain the address of a pointer");
err.help(msg);
}
err.help(
"if you can't comply with strict provenance and need to expose the pointer\
provenance you can use `.expose_addr()` instead"
);

err.emit();
},
Expand All @@ -1017,15 +1027,28 @@ impl<'a, 'tcx> CastCheck<'tcx> {
self.expr.hir_id,
self.span,
|err| {
err.build(&format!(

let mut err = err.build(&format!(
"strict provenance disallows casting integer `{}` to pointer `{}`",
self.expr_ty, self.cast_ty
))
.help(
"use `.with_addr(...)` to adjust a valid pointer \
in the same allocation, to this address",
)
.emit();
));
let msg = "use `.with_addr()` to adjust a valid pointer in the same allocation, to this address";
if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) {
err.span_suggestion(
self.span,
msg,
format!("(...).with_addr({})", snippet),
Applicability::HasPlaceholders,
);
} else {
err.help(msg);
}
err.help(
"if you can't comply with strict provenance and don't have a pointer with \
the correct provenance you can use `std::ptr::from_exposed_addr()` instead"
);

err.emit();
},
);
}
Expand Down
22 changes: 22 additions & 0 deletions src/doc/unstable-book/src/language-features/strict-provenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# `strict_provenance`

The tracking issue for this feature is: [#95228]

[#95228]: https://github.com/rust-lang/rust/issues/95228
-----

The `strict_provenance` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints.
These lint on casts between integers and pointers, that are recommended against or invalid in the strict provenance model.
The same feature gate is also used for the experimental strict provenance API in `std` (actually `core`).

## Example

```rust
#![feature(strict_provenance)]
#![warn(fuzzy_provenance_casts)]

fn main() {
let _dangling = 16_usize as *const u8;
//~^ WARNING: strict provenance disallows casting integer `usize` to pointer `*const u8`
}
```
19 changes: 19 additions & 0 deletions src/test/ui/feature-gates/feature-gate-strict_provenance.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// check-pass

#![deny(fuzzy_provenance_casts)]
//~^ WARNING unknown lint: `fuzzy_provenance_casts`
//~| WARNING unknown lint: `fuzzy_provenance_casts`
//~| WARNING unknown lint: `fuzzy_provenance_casts`
#![deny(lossy_provenance_casts)]
//~^ WARNING unknown lint: `lossy_provenance_casts`
//~| WARNING unknown lint: `lossy_provenance_casts`
//~| WARNING unknown lint: `lossy_provenance_casts`

fn main() {
// no warnings emitted since the lints are not activated

let _dangling = 16_usize as *const u8;

let x: u8 = 37;
let _addr: usize = &x as *const u8 as usize;
}
63 changes: 63 additions & 0 deletions src/test/ui/feature-gates/feature-gate-strict_provenance.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
warning: unknown lint: `fuzzy_provenance_casts`
--> $DIR/feature-gate-strict_provenance.rs:3:1
|
LL | #![deny(fuzzy_provenance_casts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unknown_lints)]` on by default
= note: the `fuzzy_provenance_casts` lint is unstable
= note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
= help: add `#![feature(strict_provenance)]` to the crate attributes to enable

warning: unknown lint: `lossy_provenance_casts`
--> $DIR/feature-gate-strict_provenance.rs:7:1
|
LL | #![deny(lossy_provenance_casts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `lossy_provenance_casts` lint is unstable
= note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
= help: add `#![feature(strict_provenance)]` to the crate attributes to enable

warning: unknown lint: `fuzzy_provenance_casts`
--> $DIR/feature-gate-strict_provenance.rs:3:1
|
LL | #![deny(fuzzy_provenance_casts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `fuzzy_provenance_casts` lint is unstable
= note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
= help: add `#![feature(strict_provenance)]` to the crate attributes to enable

warning: unknown lint: `lossy_provenance_casts`
--> $DIR/feature-gate-strict_provenance.rs:7:1
|
LL | #![deny(lossy_provenance_casts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `lossy_provenance_casts` lint is unstable
= note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
= help: add `#![feature(strict_provenance)]` to the crate attributes to enable

warning: unknown lint: `fuzzy_provenance_casts`
--> $DIR/feature-gate-strict_provenance.rs:3:1
|
LL | #![deny(fuzzy_provenance_casts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `fuzzy_provenance_casts` lint is unstable
= note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
= help: add `#![feature(strict_provenance)]` to the crate attributes to enable

warning: unknown lint: `lossy_provenance_casts`
--> $DIR/feature-gate-strict_provenance.rs:7:1
|
LL | #![deny(lossy_provenance_casts)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `lossy_provenance_casts` lint is unstable
= note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
= help: add `#![feature(strict_provenance)]` to the crate attributes to enable

warning: 6 warnings emitted

7 changes: 7 additions & 0 deletions src/test/ui/lint/lint-strict-provenance-fuzzy-casts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![feature(strict_provenance)]
#![deny(fuzzy_provenance_casts)]

fn main() {
let dangling = 16_usize as *const u8;
//~^ ERROR strict provenance disallows casting integer `usize` to pointer `*const u8`
}
19 changes: 19 additions & 0 deletions src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error: strict provenance disallows casting integer `usize` to pointer `*const u8`
--> $DIR/lint-strict-provenance-fuzzy-casts.rs:5:20
|
LL | let dangling = 16_usize as *const u8;
| ^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/lint-strict-provenance-fuzzy-casts.rs:2:9
|
LL | #![deny(fuzzy_provenance_casts)]
| ^^^^^^^^^^^^^^^^^^^^^^
= help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::from_exposed_addr()` instead
help: use `.with_addr()` to adjust a valid pointer in the same allocation, to this address
|
LL | let dangling = (...).with_addr(16_usize);
| ~~~~~~~~~~~~~~~~~~~~~~~~~

error: aborting due to previous error

11 changes: 11 additions & 0 deletions src/test/ui/lint/lint-strict-provenance-lossy-casts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![feature(strict_provenance)]
#![deny(lossy_provenance_casts)]

fn main() {
let x: u8 = 37;
let addr: usize = &x as *const u8 as usize;
//~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`

let addr_32bit = &x as *const u8 as u32;
//~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
}
Loading