mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-30 04:56:25 +03:00
Auto merge of #146052 - matthiaskrgr:rollup-cfxx9m6, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - rust-lang/rust#144443 (Make target pointer width in target json an integer) - rust-lang/rust#145174 (Ensure consistent drop for panicking drop in hint::select_unpredictable) - rust-lang/rust#145592 (Fix format string grammar in docs and improve alignment error message for rust-lang/rust#144023) - rust-lang/rust#145931 (Clarify that align_offset overaligns) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
@@ -315,7 +315,7 @@ pub enum TargetDataLayoutErrors<'a> {
|
||||
MissingAlignment { cause: &'a str },
|
||||
InvalidAlignment { cause: &'a str, err: AlignFromBytesError },
|
||||
InconsistentTargetArchitecture { dl: &'a str, target: &'a str },
|
||||
InconsistentTargetPointerWidth { pointer_size: u64, target: u32 },
|
||||
InconsistentTargetPointerWidth { pointer_size: u64, target: u16 },
|
||||
InvalidBitsSize { err: String },
|
||||
UnknownPointerSpecification { err: String },
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ pub fn bit_width(&self) -> Option<u64> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn normalize(&self, target_width: u32) -> Self {
|
||||
pub fn normalize(&self, target_width: u16) -> Self {
|
||||
match self {
|
||||
IntTy::Isize => match target_width {
|
||||
16 => IntTy::I16,
|
||||
@@ -148,7 +148,7 @@ pub fn bit_width(&self) -> Option<u64> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn normalize(&self, target_width: u32) -> Self {
|
||||
pub fn normalize(&self, target_width: u16) -> Self {
|
||||
match self {
|
||||
UintTy::Usize => match target_width {
|
||||
16 => UintTy::U16,
|
||||
|
||||
@@ -22,5 +22,5 @@
|
||||
"unix"
|
||||
],
|
||||
"target-mcount": "_mcount",
|
||||
"target-pointer-width": "32"
|
||||
"target-pointer-width": 32
|
||||
}
|
||||
|
||||
@@ -858,7 +858,9 @@ fn suggest_format_align(&mut self, alignment: char) {
|
||||
self.errors.insert(
|
||||
0,
|
||||
ParseError {
|
||||
description: "expected format parameter to occur after `:`".to_owned(),
|
||||
description:
|
||||
"expected alignment specifier after `:` in format string; example: `{:>?}`"
|
||||
.to_owned(),
|
||||
note: None,
|
||||
label: format!("expected `{}` to occur after `:`", alignment),
|
||||
span: range,
|
||||
|
||||
@@ -25,10 +25,7 @@ pub fn from_json(json: &str) -> Result<(Target, TargetWarnings), String> {
|
||||
let mut base = Target {
|
||||
llvm_target: json.llvm_target,
|
||||
metadata: Default::default(),
|
||||
pointer_width: json
|
||||
.target_pointer_width
|
||||
.parse()
|
||||
.map_err(|err| format!("invalid target-pointer-width: {err}"))?,
|
||||
pointer_width: json.target_pointer_width,
|
||||
data_layout: json.data_layout,
|
||||
arch: json.arch,
|
||||
options: Default::default(),
|
||||
@@ -245,19 +242,17 @@ fn to_json(&self) -> Json {
|
||||
target.update_to_cli();
|
||||
|
||||
macro_rules! target_val {
|
||||
($attr:ident) => {{
|
||||
let name = (stringify!($attr)).replace("_", "-");
|
||||
d.insert(name, target.$attr.to_json());
|
||||
($attr:ident) => {
|
||||
target_val!($attr, (stringify!($attr)).replace("_", "-"))
|
||||
};
|
||||
($attr:ident, $json_name:expr) => {{
|
||||
let name = $json_name;
|
||||
d.insert(name.into(), target.$attr.to_json());
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! target_option_val {
|
||||
($attr:ident) => {{
|
||||
let name = (stringify!($attr)).replace("_", "-");
|
||||
if default.$attr != target.$attr {
|
||||
d.insert(name, target.$attr.to_json());
|
||||
}
|
||||
}};
|
||||
($attr:ident) => {{ target_option_val!($attr, (stringify!($attr)).replace("_", "-")) }};
|
||||
($attr:ident, $json_name:expr) => {{
|
||||
let name = $json_name;
|
||||
if default.$attr != target.$attr {
|
||||
@@ -290,7 +285,7 @@ macro_rules! target_option_val {
|
||||
|
||||
target_val!(llvm_target);
|
||||
target_val!(metadata);
|
||||
d.insert("target-pointer-width".to_string(), self.pointer_width.to_string().to_json());
|
||||
target_val!(pointer_width, "target-pointer-width");
|
||||
target_val!(arch);
|
||||
target_val!(data_layout);
|
||||
|
||||
@@ -463,7 +458,7 @@ struct TargetSpecJsonMetadata {
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct TargetSpecJson {
|
||||
llvm_target: StaticCow<str>,
|
||||
target_pointer_width: String,
|
||||
target_pointer_width: u16,
|
||||
data_layout: StaticCow<str>,
|
||||
arch: StaticCow<str>,
|
||||
|
||||
|
||||
@@ -2331,7 +2331,7 @@ pub struct Target {
|
||||
/// Used for generating target documentation.
|
||||
pub metadata: TargetMetadata,
|
||||
/// Number of bits in a pointer. Influences the `target_pointer_width` `cfg` variable.
|
||||
pub pointer_width: u32,
|
||||
pub pointer_width: u16,
|
||||
/// Architecture to use for ABI considerations. Valid options include: "x86",
|
||||
/// "x86_64", "arm", "aarch64", "mips", "powerpc", "powerpc64", and others.
|
||||
pub arch: StaticCow<str>,
|
||||
|
||||
@@ -7,7 +7,7 @@ fn report_unused_fields() {
|
||||
"arch": "powerpc64",
|
||||
"data-layout": "e-m:e-i64:64-n32:64",
|
||||
"llvm-target": "powerpc64le-elf",
|
||||
"target-pointer-width": "64",
|
||||
"target-pointer-width": 64,
|
||||
"code-mode": "foo"
|
||||
}
|
||||
"#;
|
||||
|
||||
@@ -354,7 +354,7 @@
|
||||
//! sign := '+' | '-'
|
||||
//! width := count
|
||||
//! precision := count | '*'
|
||||
//! type := '?' | 'x?' | 'X?' | identifier
|
||||
//! type := '?' | 'x?' | 'X?' | 'o' | 'x' | 'X' | 'p' | 'b' | 'e' | 'E'
|
||||
//! count := parameter | integer
|
||||
//! parameter := argument '$'
|
||||
//! ```
|
||||
|
||||
@@ -19,5 +19,5 @@
|
||||
},
|
||||
"panic-strategy": "abort",
|
||||
"relocation-model": "static",
|
||||
"target-pointer-width": "32"
|
||||
"target-pointer-width": 32
|
||||
}
|
||||
|
||||
@@ -776,12 +776,45 @@ pub fn select_unpredictable<T>(condition: bool, true_val: T, false_val: T) -> T
|
||||
// Change this to use ManuallyDrop instead.
|
||||
let mut true_val = MaybeUninit::new(true_val);
|
||||
let mut false_val = MaybeUninit::new(false_val);
|
||||
|
||||
struct DropOnPanic<T> {
|
||||
// Invariant: valid pointer and points to an initialized value that is not further used,
|
||||
// i.e. it can be dropped by this guard.
|
||||
inner: *mut T,
|
||||
}
|
||||
|
||||
impl<T> Drop for DropOnPanic<T> {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY: Must be guaranteed on construction of local type `DropOnPanic`.
|
||||
unsafe { self.inner.drop_in_place() }
|
||||
}
|
||||
}
|
||||
|
||||
let true_ptr = true_val.as_mut_ptr();
|
||||
let false_ptr = false_val.as_mut_ptr();
|
||||
|
||||
// SAFETY: The value that is not selected is dropped, and the selected one
|
||||
// is returned. This is necessary because the intrinsic doesn't drop the
|
||||
// value that is not selected.
|
||||
unsafe {
|
||||
crate::intrinsics::select_unpredictable(!condition, &mut true_val, &mut false_val)
|
||||
.assume_init_drop();
|
||||
// Extract the selected value first, ensure it is dropped as well if dropping the unselected
|
||||
// value panics. We construct a temporary by-pointer guard around the selected value while
|
||||
// dropping the unselected value. Arguments overlap here, so we can not use mutable
|
||||
// reference for these arguments.
|
||||
let guard = crate::intrinsics::select_unpredictable(condition, true_ptr, false_ptr);
|
||||
let drop = crate::intrinsics::select_unpredictable(condition, false_ptr, true_ptr);
|
||||
|
||||
// SAFETY: both pointers are well-aligned and point to initialized values inside a
|
||||
// `MaybeUninit` each. In both possible values for `condition` the pointer `guard` and
|
||||
// `drop` do not alias (even though the two argument pairs we have selected from did alias
|
||||
// each other).
|
||||
let guard = DropOnPanic { inner: guard };
|
||||
drop.drop_in_place();
|
||||
crate::mem::forget(guard);
|
||||
|
||||
// Note that it is important to use the values here. Reading from the pointer we got makes
|
||||
// LLVM forget the !unpredictable annotation sometimes (in tests, integer sized values in
|
||||
// particular seemed to confuse it, also observed in llvm/llvm-project #82340).
|
||||
crate::intrinsics::select_unpredictable(condition, true_val, false_val).assume_init()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2166,10 +2166,9 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Align pointer `p`.
|
||||
/// Calculate an element-offset that increases a pointer's alignment.
|
||||
///
|
||||
/// Calculate offset (in terms of elements of `size_of::<T>()` stride) that has to be applied
|
||||
/// to pointer `p` so that pointer `p` would get aligned to `a`.
|
||||
/// Calculate an element-offset (not byte-offset) that when added to a given pointer `p`, increases `p`'s alignment to at least the given alignment `a`.
|
||||
///
|
||||
/// # Safety
|
||||
/// `a` must be a power of two.
|
||||
|
||||
@@ -21,3 +21,39 @@ fn drop(&mut self) {
|
||||
assert!(a_dropped.get());
|
||||
assert!(b_dropped.get());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "message canary"]
|
||||
fn select_unpredictable_drop_on_panic() {
|
||||
use core::cell::Cell;
|
||||
|
||||
struct X<'a> {
|
||||
cell: &'a Cell<u16>,
|
||||
expect: u16,
|
||||
write: u16,
|
||||
}
|
||||
|
||||
impl Drop for X<'_> {
|
||||
fn drop(&mut self) {
|
||||
let value = self.cell.get();
|
||||
self.cell.set(self.write);
|
||||
assert_eq!(value, self.expect, "message canary");
|
||||
}
|
||||
}
|
||||
|
||||
let cell = Cell::new(0);
|
||||
|
||||
// Trigger a double-panic if the selected cell was not dropped during panic.
|
||||
let _armed = X { cell: &cell, expect: 0xdead, write: 0 };
|
||||
let selected = X { cell: &cell, write: 0xdead, expect: 1 };
|
||||
let unselected = X { cell: &cell, write: 1, expect: 0xff };
|
||||
|
||||
// The correct drop order is:
|
||||
//
|
||||
// 1. `unselected` drops, writes 1, and panics as 0 != 0xff
|
||||
// 2. `selected` drops during unwind, writes 0xdead and does not panic as 1 == 1
|
||||
// 3. `armed` drops during unwind, writes 0 and does not panic as 0xdead == 0xdead
|
||||
//
|
||||
// If `selected` is not dropped, `armed` panics as 1 != 0xdead
|
||||
let _unreachable = core::hint::select_unpredictable(true, selected, unselected);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
LINUX_VERSION=v6.16-rc1
|
||||
# https://github.com/rust-lang/rust/pull/144443
|
||||
LINUX_VERSION=7770d51bce622b13195b2d3c85407282fc9c27e5
|
||||
|
||||
# Build rustc, rustdoc, cargo, clippy-driver and rustfmt
|
||||
../x.py build --stage 2 library rustdoc clippy rustfmt
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
use build_helper::git::GitConfig;
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
use semver::Version;
|
||||
use serde::de::{Deserialize, Deserializer, Error as _};
|
||||
|
||||
use crate::executor::ColorConfig;
|
||||
use crate::fatal;
|
||||
@@ -1072,7 +1071,7 @@ pub struct TargetCfg {
|
||||
pub(crate) abi: String,
|
||||
#[serde(rename = "target-family", default)]
|
||||
pub(crate) families: Vec<String>,
|
||||
#[serde(rename = "target-pointer-width", deserialize_with = "serde_parse_u32")]
|
||||
#[serde(rename = "target-pointer-width")]
|
||||
pub(crate) pointer_width: u32,
|
||||
#[serde(rename = "target-endian", default)]
|
||||
endian: Endian,
|
||||
@@ -1182,11 +1181,6 @@ fn query_rustc_output(config: &Config, args: &[&str], envs: HashMap<String, Stri
|
||||
String::from_utf8(output.stdout).unwrap()
|
||||
}
|
||||
|
||||
fn serde_parse_u32<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u32, D::Error> {
|
||||
let string = String::deserialize(deserializer)?;
|
||||
string.parse().map_err(D::Error::custom)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TestPaths {
|
||||
pub file: Utf8PathBuf, // e.g., compile-test/foo/bar/baz.rs
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"llvm-target": "x86_64-unknown-none",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "64",
|
||||
"target-pointer-width": 64,
|
||||
"target-c-int-width": 32,
|
||||
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
|
||||
"arch": "x86_64",
|
||||
|
||||
@@ -53,5 +53,5 @@
|
||||
"target-family": [
|
||||
"unix"
|
||||
],
|
||||
"target-pointer-width": "64"
|
||||
"target-pointer-width": 64
|
||||
}
|
||||
|
||||
@@ -33,5 +33,5 @@
|
||||
"thread"
|
||||
],
|
||||
"target-family": "unix",
|
||||
"target-pointer-width": "64"
|
||||
"target-pointer-width": 64
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"linker-flavor": "gcc",
|
||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||
"target-endian": "big",
|
||||
"target-pointer-width": "64",
|
||||
"target-pointer-width": 64,
|
||||
"arch": "x86_64",
|
||||
"os": "linux"
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
"arch": "x86_64",
|
||||
"data-layout": "e-m:e-i64:16:32:64",
|
||||
"llvm-target": "x86_64-unknown-unknown-gnu",
|
||||
"target-pointer-width": "64"
|
||||
"target-pointer-width": 64
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"linker-flavor": "gcc",
|
||||
"llvm-target": "i686-unknown-linux-gnu",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "32",
|
||||
"target-pointer-width": 32,
|
||||
"arch": "x86",
|
||||
"os": "linux"
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"data-layout": "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32",
|
||||
"linker-flavor": "gcc",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "32",
|
||||
"target-pointer-width": 32,
|
||||
"arch": "x86",
|
||||
"os": "foo"
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"linker-flavor": "gcc",
|
||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "64",
|
||||
"target-pointer-width": 64,
|
||||
"arch": "x86_64",
|
||||
"os": "linux"
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"linker-flavor": "gcc",
|
||||
"llvm-target": "i686-unknown-linux-gnu",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "32",
|
||||
"target-pointer-width": 32,
|
||||
"arch": "x86",
|
||||
"os": "linux",
|
||||
"need-explicit-cpu": true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
|
||||
"arch": "x86_64",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "64",
|
||||
"target-pointer-width": 64,
|
||||
"os": "ericos",
|
||||
"linker-flavor": "ld.lld",
|
||||
"linker": "rust-lld",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
||||
"arch": "x86_64",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "64",
|
||||
"target-pointer-width": 64,
|
||||
"os": "none",
|
||||
"linker-flavor": "ld.lld",
|
||||
"linker": "rust-lld",
|
||||
|
||||
@@ -13,9 +13,11 @@ fn main() {
|
||||
format!("{?:#?}", bar);
|
||||
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
||||
format!("Hello {<5:}!", "x");
|
||||
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
||||
//~^ ERROR invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
|
||||
format!("Hello {^5:}!", "x");
|
||||
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
||||
//~^ ERROR invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
|
||||
format!("Hello {>5:}!", "x");
|
||||
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
||||
//~^ ERROR invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
|
||||
println!("{0:#X>18}", 12345);
|
||||
//~^ ERROR invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
|
||||
}
|
||||
|
||||
@@ -50,23 +50,29 @@ LL | format!("{?:#?}", bar);
|
||||
|
|
||||
= note: `?` comes after `:`, try `:?` instead
|
||||
|
||||
error: invalid format string: expected format parameter to occur after `:`
|
||||
error: invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
|
||||
--> $DIR/format-string-wrong-order.rs:15:21
|
||||
|
|
||||
LL | format!("Hello {<5:}!", "x");
|
||||
| ^ expected `<` to occur after `:` in format string
|
||||
|
||||
error: invalid format string: expected format parameter to occur after `:`
|
||||
error: invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
|
||||
--> $DIR/format-string-wrong-order.rs:17:21
|
||||
|
|
||||
LL | format!("Hello {^5:}!", "x");
|
||||
| ^ expected `^` to occur after `:` in format string
|
||||
|
||||
error: invalid format string: expected format parameter to occur after `:`
|
||||
error: invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
|
||||
--> $DIR/format-string-wrong-order.rs:19:21
|
||||
|
|
||||
LL | format!("Hello {>5:}!", "x");
|
||||
| ^ expected `>` to occur after `:` in format string
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error: invalid format string: expected alignment specifier after `:` in format string; example: `{:>?}`
|
||||
--> $DIR/format-string-wrong-order.rs:21:20
|
||||
|
|
||||
LL | println!("{0:#X>18}", 12345);
|
||||
| ^ expected `>` to occur after `:` in format string
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
|
||||
Reference in New Issue
Block a user