Skip to content

Commit 68369a0

Browse files
committed
Auto merge of rust-lang#94254 - matthiaskrgr:rollup-7llbjhd, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#94169 (Fix several asm! related issues) - rust-lang#94178 (tidy: fire less "ignoring file length unneccessarily" warnings) - rust-lang#94179 (solarish current_exe using libc call directly) - rust-lang#94196 (compiletest: Print process output info with less whitespace) - rust-lang#94208 (Add the let else tests found missing in the stabilization report) - rust-lang#94237 (Do not suggest wrapping an item if it has ambiguous un-imported methods) - rust-lang#94246 (ScalarMaybeUninit is explicitly hexadecimal in its formatting) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 9ecd75b + e381462 commit 68369a0

36 files changed

+488
-307
lines changed

compiler/rustc_ast_lowering/src/asm.rs

+7-19
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
6464
let mut clobber_abis = FxHashMap::default();
6565
if let Some(asm_arch) = asm_arch {
6666
for (abi_name, abi_span) in &asm.clobber_abis {
67-
match asm::InlineAsmClobberAbi::parse(
68-
asm_arch,
69-
&self.sess.target_features,
70-
&self.sess.target,
71-
*abi_name,
72-
) {
67+
match asm::InlineAsmClobberAbi::parse(asm_arch, &self.sess.target, *abi_name) {
7368
Ok(abi) => {
7469
// If the abi was already in the list, emit an error
7570
match clobber_abis.get(&abi) {
@@ -129,17 +124,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
129124
.operands
130125
.iter()
131126
.map(|(op, op_sp)| {
132-
let lower_reg = |reg, is_clobber| match reg {
127+
let lower_reg = |reg| match reg {
133128
InlineAsmRegOrRegClass::Reg(s) => {
134129
asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch {
135-
asm::InlineAsmReg::parse(
136-
asm_arch,
137-
&sess.target_features,
138-
&sess.target,
139-
is_clobber,
140-
s,
141-
)
142-
.unwrap_or_else(|e| {
130+
asm::InlineAsmReg::parse(asm_arch, s).unwrap_or_else(|e| {
143131
let msg = format!("invalid register `{}`: {}", s.as_str(), e);
144132
sess.struct_span_err(*op_sp, &msg).emit();
145133
asm::InlineAsmReg::Err
@@ -163,24 +151,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
163151

164152
let op = match *op {
165153
InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In {
166-
reg: lower_reg(reg, false),
154+
reg: lower_reg(reg),
167155
expr: self.lower_expr_mut(expr),
168156
},
169157
InlineAsmOperand::Out { reg, late, ref expr } => hir::InlineAsmOperand::Out {
170-
reg: lower_reg(reg, expr.is_none()),
158+
reg: lower_reg(reg),
171159
late,
172160
expr: expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
173161
},
174162
InlineAsmOperand::InOut { reg, late, ref expr } => {
175163
hir::InlineAsmOperand::InOut {
176-
reg: lower_reg(reg, false),
164+
reg: lower_reg(reg),
177165
late,
178166
expr: self.lower_expr_mut(expr),
179167
}
180168
}
181169
InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => {
182170
hir::InlineAsmOperand::SplitInOut {
183-
reg: lower_reg(reg, false),
171+
reg: lower_reg(reg),
184172
late,
185173
in_expr: self.lower_expr_mut(in_expr),
186174
out_expr: out_expr.as_ref().map(|expr| self.lower_expr_mut(expr)),

compiler/rustc_codegen_cranelift/src/inline_asm.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
106106
let mut asm_gen = InlineAssemblyGenerator {
107107
tcx: fx.tcx,
108108
arch: fx.tcx.sess.asm_arch.unwrap(),
109+
enclosing_def_id: fx.instance.def_id(),
109110
template,
110111
operands,
111112
options,
@@ -169,6 +170,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
169170
struct InlineAssemblyGenerator<'a, 'tcx> {
170171
tcx: TyCtxt<'tcx>,
171172
arch: InlineAsmArch,
173+
enclosing_def_id: DefId,
172174
template: &'a [InlineAsmTemplatePiece],
173175
operands: &'a [InlineAsmOperand<'tcx>],
174176
options: InlineAsmOptions,
@@ -182,7 +184,12 @@ struct InlineAssemblyGenerator<'a, 'tcx> {
182184
impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
183185
fn allocate_registers(&mut self) {
184186
let sess = self.tcx.sess;
185-
let map = allocatable_registers(self.arch, &sess.target_features, &sess.target);
187+
let map = allocatable_registers(
188+
self.arch,
189+
sess.relocation_model(),
190+
self.tcx.asm_target_features(self.enclosing_def_id),
191+
&sess.target,
192+
);
186193
let mut allocated = FxHashMap::<_, (bool, bool)>::default();
187194
let mut regs = vec![None; self.operands.len()];
188195

@@ -313,14 +320,9 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
313320
let mut new_slot = |x| new_slot_fn(&mut slot_size, x);
314321

315322
// Allocate stack slots for saving clobbered registers
316-
let abi_clobber = InlineAsmClobberAbi::parse(
317-
self.arch,
318-
&self.tcx.sess.target_features,
319-
&self.tcx.sess.target,
320-
sym::C,
321-
)
322-
.unwrap()
323-
.clobbered_regs();
323+
let abi_clobber = InlineAsmClobberAbi::parse(self.arch, &self.tcx.sess.target, sym::C)
324+
.unwrap()
325+
.clobbered_regs();
324326
for (i, reg) in self.registers.iter().enumerate().filter_map(|(i, r)| r.map(|r| (i, r))) {
325327
let mut need_save = true;
326328
// If the register overlaps with a register clobbered by function call, then

compiler/rustc_codegen_ssa/src/target_features.rs

-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
3636
// #[target_feature].
3737
("thumb-mode", Some(sym::arm_target_feature)),
3838
("thumb2", Some(sym::arm_target_feature)),
39-
("reserve-r9", Some(sym::arm_target_feature)),
4039
];
4140

4241
const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[

compiler/rustc_const_eval/src/interpret/operand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,11 @@ impl<Tag: Provenance> std::fmt::Display for ImmTy<'_, Tag> {
142142
p(cx, s, ty)?;
143143
return Ok(());
144144
}
145-
write!(f, "{}: {}", s, self.layout.ty)
145+
write!(f, "{:x}: {}", s, self.layout.ty)
146146
}
147147
Immediate::ScalarPair(a, b) => {
148148
// FIXME(oli-obk): at least print tuples and slices nicely
149-
write!(f, "({}, {}): {}", a, b, self.layout.ty,)
149+
write!(f, "({:x}, {:x}): {}", a, b, self.layout.ty,)
150150
}
151151
}
152152
})

compiler/rustc_const_eval/src/interpret/validity.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
503503
value.to_bool(),
504504
self.path,
505505
err_ub!(InvalidBool(..)) | err_ub!(InvalidUninitBytes(None)) =>
506-
{ "{}", value } expected { "a boolean" },
506+
{ "{:x}", value } expected { "a boolean" },
507507
);
508508
Ok(true)
509509
}
@@ -513,7 +513,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
513513
value.to_char(),
514514
self.path,
515515
err_ub!(InvalidChar(..)) | err_ub!(InvalidUninitBytes(None)) =>
516-
{ "{}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" },
516+
{ "{:x}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" },
517517
);
518518
Ok(true)
519519
}
@@ -526,7 +526,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
526526
let is_bits = value.check_init().map_or(false, |v| v.try_to_int().is_ok());
527527
if !is_bits {
528528
throw_validation_failure!(self.path,
529-
{ "{}", value } expected { "initialized plain (non-pointer) bytes" }
529+
{ "{:x}", value } expected { "initialized plain (non-pointer) bytes" }
530530
)
531531
}
532532
}
@@ -580,7 +580,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
580580
err_ub!(DanglingIntPointer(..)) |
581581
err_ub!(InvalidFunctionPointer(..)) |
582582
err_ub!(InvalidUninitBytes(None)) =>
583-
{ "{}", value } expected { "a function pointer" },
583+
{ "{:x}", value } expected { "a function pointer" },
584584
);
585585
// FIXME: Check if the signature matches
586586
Ok(true)
@@ -632,7 +632,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
632632
let value = try_validation!(
633633
value.check_init(),
634634
self.path,
635-
err_ub!(InvalidUninitBytes(None)) => { "{}", value }
635+
err_ub!(InvalidUninitBytes(None)) => { "{:x}", value }
636636
expected { "something {}", wrapping_range_format(valid_range, max_value) },
637637
);
638638
let bits = match value.try_to_int() {

compiler/rustc_middle/src/mir/interpret/value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ impl<Tag: Provenance> fmt::Debug for ScalarMaybeUninit<Tag> {
498498
}
499499
}
500500

501-
impl<Tag: Provenance> fmt::Display for ScalarMaybeUninit<Tag> {
501+
impl<Tag: Provenance> fmt::LowerHex for ScalarMaybeUninit<Tag> {
502502
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
503503
match self {
504504
ScalarMaybeUninit::Uninit => write!(f, "uninitialized bytes"),

compiler/rustc_middle/src/query/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,10 @@ rustc_queries! {
10461046
cache_on_disk_if { true }
10471047
}
10481048

1049+
query asm_target_features(def_id: DefId) -> &'tcx FxHashSet<Symbol> {
1050+
desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) }
1051+
}
1052+
10491053
query fn_arg_names(def_id: DefId) -> &'tcx [rustc_span::symbol::Ident] {
10501054
desc { |tcx| "looking up function parameter names for `{}`", tcx.def_path_str(def_id) }
10511055
separate_provide_extern

compiler/rustc_passes/src/intrinsicck.rs

+28-15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use rustc_ast::InlineAsmTemplatePiece;
2+
use rustc_data_structures::stable_set::FxHashSet;
23
use rustc_errors::struct_span_err;
34
use rustc_hir as hir;
45
use rustc_hir::def::{DefKind, Res};
@@ -138,7 +139,7 @@ impl<'tcx> ExprVisitor<'tcx> {
138139
template: &[InlineAsmTemplatePiece],
139140
is_input: bool,
140141
tied_input: Option<(&hir::Expr<'tcx>, Option<InlineAsmType>)>,
141-
target_features: &[Symbol],
142+
target_features: &FxHashSet<Symbol>,
142143
) -> Option<InlineAsmType> {
143144
// Check the type against the allowed types for inline asm.
144145
let ty = self.typeck_results.expr_ty_adjusted(expr);
@@ -285,9 +286,7 @@ impl<'tcx> ExprVisitor<'tcx> {
285286
// (!). In that case we still need the earlier check to verify that the
286287
// register class is usable at all.
287288
if let Some(feature) = feature {
288-
if !self.tcx.sess.target_features.contains(&feature)
289-
&& !target_features.contains(&feature)
290-
{
289+
if !target_features.contains(&feature) {
291290
let msg = &format!("`{}` target feature is not enabled", feature);
292291
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
293292
err.note(&format!(
@@ -347,7 +346,8 @@ impl<'tcx> ExprVisitor<'tcx> {
347346
let hir = self.tcx.hir();
348347
let enclosing_id = hir.enclosing_body_owner(hir_id);
349348
let enclosing_def_id = hir.local_def_id(enclosing_id).to_def_id();
350-
let attrs = self.tcx.codegen_fn_attrs(enclosing_def_id);
349+
let target_features = self.tcx.asm_target_features(enclosing_def_id);
350+
let asm_arch = self.tcx.sess.asm_arch.unwrap();
351351
for (idx, (op, op_sp)) in asm.operands.iter().enumerate() {
352352
// Validate register classes against currently enabled target
353353
// features. We check that at least one type is available for
@@ -360,16 +360,29 @@ impl<'tcx> ExprVisitor<'tcx> {
360360
// Note that this is only possible for explicit register
361361
// operands, which cannot be used in the asm string.
362362
if let Some(reg) = op.reg() {
363+
// Some explicit registers cannot be used depending on the
364+
// target. Reject those here.
365+
if let InlineAsmRegOrRegClass::Reg(reg) = reg {
366+
if let Err(msg) = reg.validate(
367+
asm_arch,
368+
self.tcx.sess.relocation_model(),
369+
&target_features,
370+
&self.tcx.sess.target,
371+
op.is_clobber(),
372+
) {
373+
let msg = format!("cannot use register `{}`: {}", reg.name(), msg);
374+
self.tcx.sess.struct_span_err(*op_sp, &msg).emit();
375+
continue;
376+
}
377+
}
378+
363379
if !op.is_clobber() {
364380
let mut missing_required_features = vec![];
365381
let reg_class = reg.reg_class();
366-
for &(_, feature) in reg_class.supported_types(self.tcx.sess.asm_arch.unwrap())
367-
{
382+
for &(_, feature) in reg_class.supported_types(asm_arch) {
368383
match feature {
369384
Some(feature) => {
370-
if self.tcx.sess.target_features.contains(&feature)
371-
|| attrs.target_features.contains(&feature)
372-
{
385+
if target_features.contains(&feature) {
373386
missing_required_features.clear();
374387
break;
375388
} else {
@@ -425,7 +438,7 @@ impl<'tcx> ExprVisitor<'tcx> {
425438
asm.template,
426439
true,
427440
None,
428-
&attrs.target_features,
441+
&target_features,
429442
);
430443
}
431444
hir::InlineAsmOperand::Out { reg, late: _, ref expr } => {
@@ -437,7 +450,7 @@ impl<'tcx> ExprVisitor<'tcx> {
437450
asm.template,
438451
false,
439452
None,
440-
&attrs.target_features,
453+
&target_features,
441454
);
442455
}
443456
}
@@ -449,7 +462,7 @@ impl<'tcx> ExprVisitor<'tcx> {
449462
asm.template,
450463
false,
451464
None,
452-
&attrs.target_features,
465+
&target_features,
453466
);
454467
}
455468
hir::InlineAsmOperand::SplitInOut { reg, late: _, ref in_expr, ref out_expr } => {
@@ -460,7 +473,7 @@ impl<'tcx> ExprVisitor<'tcx> {
460473
asm.template,
461474
true,
462475
None,
463-
&attrs.target_features,
476+
&target_features,
464477
);
465478
if let Some(out_expr) = out_expr {
466479
self.check_asm_operand_type(
@@ -470,7 +483,7 @@ impl<'tcx> ExprVisitor<'tcx> {
470483
asm.template,
471484
false,
472485
Some((in_expr, in_ty)),
473-
&attrs.target_features,
486+
&target_features,
474487
);
475488
}
476489
}

compiler/rustc_span/src/symbol.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,6 @@ symbols! {
11221122
repr_packed,
11231123
repr_simd,
11241124
repr_transparent,
1125-
reserved_r9: "reserved-r9",
11261125
residual,
11271126
result,
11281127
rhs,

compiler/rustc_target/src/asm/aarch64.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::{InlineAsmArch, InlineAsmType};
2-
use crate::spec::Target;
2+
use crate::spec::{RelocModel, Target};
33
use rustc_data_structures::stable_set::FxHashSet;
44
use rustc_macros::HashStable_Generic;
55
use rustc_span::Symbol;
@@ -73,17 +73,18 @@ impl AArch64InlineAsmRegClass {
7373
}
7474
}
7575

76-
pub fn reserved_x18(
76+
pub fn target_reserves_x18(target: &Target) -> bool {
77+
target.os == "android" || target.is_like_fuchsia || target.is_like_osx || target.is_like_windows
78+
}
79+
80+
fn reserved_x18(
7781
_arch: InlineAsmArch,
82+
_reloc_model: RelocModel,
7883
_target_features: &FxHashSet<Symbol>,
7984
target: &Target,
8085
_is_clobber: bool,
8186
) -> Result<(), &'static str> {
82-
if target.os == "android"
83-
|| target.is_like_fuchsia
84-
|| target.is_like_osx
85-
|| target.is_like_windows
86-
{
87+
if target_reserves_x18(target) {
8788
Err("x18 is a reserved register on this target")
8889
} else {
8990
Ok(())

0 commit comments

Comments
 (0)