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

Rollup of 7 pull requests #94254

Merged
merged 19 commits into from
Feb 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
49a5456
tidy: fire less "ignoring file length unneccessarily" warnings
est31 Feb 20, 2022
f810314
solarish current_exe using libc call directly
devnexen Feb 20, 2022
c97f05c
compiletest: Print process output info with less whitespace
aDotInTheVoid Feb 20, 2022
e7730dc
Expand let-else allow tests
est31 Feb 21, 2022
5bd7106
Add regression test for #92069
est31 Feb 21, 2022
2e8a766
Simplify gating of BPF w registers behind the alu32 target feature
Amanieu Feb 17, 2022
1ceb104
On ARM, use relocation_model to detect whether r9 should be reserved
Amanieu Feb 17, 2022
fc41d4b
Take CodegenFnAttrs into account when validating asm! register operands
Amanieu Feb 17, 2022
fb5539b
Add tests
Amanieu Feb 19, 2022
a60b791
Add ignore-tidy-filelength
Amanieu Feb 21, 2022
0626919
Do not suggest wrapping an item if it has ambiguous un-imported methods
compiler-errors Feb 22, 2022
fb1ee87
ScalarMaybeUninit is explicitly hexadecimal in its formatting
RalfJung Feb 22, 2022
1cf2e69
Rollup merge of #94169 - Amanieu:asm_stuff, r=nagisa
matthiaskrgr Feb 22, 2022
a53b604
Rollup merge of #94178 - est31:tolerant_lines_check, r=Mark-Simulacrum
matthiaskrgr Feb 22, 2022
21fb814
Rollup merge of #94179 - devnexen:getexecname_directcall, r=kennytm
matthiaskrgr Feb 22, 2022
1177b30
Rollup merge of #94196 - aDotInTheVoid:terse-procres-info, r=Mark-Sim…
matthiaskrgr Feb 22, 2022
b322382
Rollup merge of #94208 - est31:let_else, r=Mark-Simulacrum
matthiaskrgr Feb 22, 2022
396910a
Rollup merge of #94237 - compiler-errors:dont-wrap-ambiguous-receiver…
matthiaskrgr Feb 22, 2022
e381462
Rollup merge of #94246 - RalfJung:hex, r=oli-obk
matthiaskrgr Feb 22, 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
26 changes: 7 additions & 19 deletions compiler/rustc_ast_lowering/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let mut clobber_abis = FxHashMap::default();
if let Some(asm_arch) = asm_arch {
for (abi_name, abi_span) in &asm.clobber_abis {
match asm::InlineAsmClobberAbi::parse(
asm_arch,
&self.sess.target_features,
&self.sess.target,
*abi_name,
) {
match asm::InlineAsmClobberAbi::parse(asm_arch, &self.sess.target, *abi_name) {
Ok(abi) => {
// If the abi was already in the list, emit an error
match clobber_abis.get(&abi) {
Expand Down Expand Up @@ -129,17 +124,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.operands
.iter()
.map(|(op, op_sp)| {
let lower_reg = |reg, is_clobber| match reg {
let lower_reg = |reg| match reg {
InlineAsmRegOrRegClass::Reg(s) => {
asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch {
asm::InlineAsmReg::parse(
asm_arch,
&sess.target_features,
&sess.target,
is_clobber,
s,
)
.unwrap_or_else(|e| {
asm::InlineAsmReg::parse(asm_arch, s).unwrap_or_else(|e| {
let msg = format!("invalid register `{}`: {}", s.as_str(), e);
sess.struct_span_err(*op_sp, &msg).emit();
asm::InlineAsmReg::Err
Expand All @@ -163,24 +151,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

let op = match *op {
InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In {
reg: lower_reg(reg, false),
reg: lower_reg(reg),
expr: self.lower_expr_mut(expr),
},
InlineAsmOperand::Out { reg, late, ref expr } => hir::InlineAsmOperand::Out {
reg: lower_reg(reg, expr.is_none()),
reg: lower_reg(reg),
late,
expr: expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
},
InlineAsmOperand::InOut { reg, late, ref expr } => {
hir::InlineAsmOperand::InOut {
reg: lower_reg(reg, false),
reg: lower_reg(reg),
late,
expr: self.lower_expr_mut(expr),
}
}
InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => {
hir::InlineAsmOperand::SplitInOut {
reg: lower_reg(reg, false),
reg: lower_reg(reg),
late,
in_expr: self.lower_expr_mut(in_expr),
out_expr: out_expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
Expand Down
20 changes: 11 additions & 9 deletions compiler/rustc_codegen_cranelift/src/inline_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
let mut asm_gen = InlineAssemblyGenerator {
tcx: fx.tcx,
arch: fx.tcx.sess.asm_arch.unwrap(),
enclosing_def_id: fx.instance.def_id(),
template,
operands,
options,
Expand Down Expand Up @@ -169,6 +170,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
struct InlineAssemblyGenerator<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
arch: InlineAsmArch,
enclosing_def_id: DefId,
template: &'a [InlineAsmTemplatePiece],
operands: &'a [InlineAsmOperand<'tcx>],
options: InlineAsmOptions,
Expand All @@ -182,7 +184,12 @@ struct InlineAssemblyGenerator<'a, 'tcx> {
impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
fn allocate_registers(&mut self) {
let sess = self.tcx.sess;
let map = allocatable_registers(self.arch, &sess.target_features, &sess.target);
let map = allocatable_registers(
self.arch,
sess.relocation_model(),
self.tcx.asm_target_features(self.enclosing_def_id),
&sess.target,
);
let mut allocated = FxHashMap::<_, (bool, bool)>::default();
let mut regs = vec![None; self.operands.len()];

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

// Allocate stack slots for saving clobbered registers
let abi_clobber = InlineAsmClobberAbi::parse(
self.arch,
&self.tcx.sess.target_features,
&self.tcx.sess.target,
sym::C,
)
.unwrap()
.clobbered_regs();
let abi_clobber = InlineAsmClobberAbi::parse(self.arch, &self.tcx.sess.target, sym::C)
.unwrap()
.clobbered_regs();
for (i, reg) in self.registers.iter().enumerate().filter_map(|(i, r)| r.map(|r| (i, r))) {
let mut need_save = true;
// If the register overlaps with a register clobbered by function call, then
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
// #[target_feature].
("thumb-mode", Some(sym::arm_target_feature)),
("thumb2", Some(sym::arm_target_feature)),
("reserve-r9", Some(sym::arm_target_feature)),
];

const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,11 @@ impl<Tag: Provenance> std::fmt::Display for ImmTy<'_, Tag> {
p(cx, s, ty)?;
return Ok(());
}
write!(f, "{}: {}", s, self.layout.ty)
write!(f, "{:x}: {}", s, self.layout.ty)
}
Immediate::ScalarPair(a, b) => {
// FIXME(oli-obk): at least print tuples and slices nicely
write!(f, "({}, {}): {}", a, b, self.layout.ty,)
write!(f, "({:x}, {:x}): {}", a, b, self.layout.ty,)
}
}
})
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
value.to_bool(),
self.path,
err_ub!(InvalidBool(..)) | err_ub!(InvalidUninitBytes(None)) =>
{ "{}", value } expected { "a boolean" },
{ "{:x}", value } expected { "a boolean" },
);
Ok(true)
}
Expand All @@ -513,7 +513,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
value.to_char(),
self.path,
err_ub!(InvalidChar(..)) | err_ub!(InvalidUninitBytes(None)) =>
{ "{}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" },
{ "{:x}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" },
);
Ok(true)
}
Expand All @@ -526,7 +526,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
let is_bits = value.check_init().map_or(false, |v| v.try_to_int().is_ok());
if !is_bits {
throw_validation_failure!(self.path,
{ "{}", value } expected { "initialized plain (non-pointer) bytes" }
{ "{:x}", value } expected { "initialized plain (non-pointer) bytes" }
)
}
}
Expand Down Expand Up @@ -580,7 +580,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
err_ub!(DanglingIntPointer(..)) |
err_ub!(InvalidFunctionPointer(..)) |
err_ub!(InvalidUninitBytes(None)) =>
{ "{}", value } expected { "a function pointer" },
{ "{:x}", value } expected { "a function pointer" },
);
// FIXME: Check if the signature matches
Ok(true)
Expand Down Expand Up @@ -632,7 +632,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
let value = try_validation!(
value.check_init(),
self.path,
err_ub!(InvalidUninitBytes(None)) => { "{}", value }
err_ub!(InvalidUninitBytes(None)) => { "{:x}", value }
expected { "something {}", wrapping_range_format(valid_range, max_value) },
);
let bits = match value.try_to_int() {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/interpret/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ impl<Tag: Provenance> fmt::Debug for ScalarMaybeUninit<Tag> {
}
}

impl<Tag: Provenance> fmt::Display for ScalarMaybeUninit<Tag> {
impl<Tag: Provenance> fmt::LowerHex for ScalarMaybeUninit<Tag> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ScalarMaybeUninit::Uninit => write!(f, "uninitialized bytes"),
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,10 @@ rustc_queries! {
cache_on_disk_if { true }
}

query asm_target_features(def_id: DefId) -> &'tcx FxHashSet<Symbol> {
desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) }
}

query fn_arg_names(def_id: DefId) -> &'tcx [rustc_span::symbol::Ident] {
desc { |tcx| "looking up function parameter names for `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
Expand Down
43 changes: 28 additions & 15 deletions compiler/rustc_passes/src/intrinsicck.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rustc_ast::InlineAsmTemplatePiece;
use rustc_data_structures::stable_set::FxHashSet;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
Expand Down Expand Up @@ -138,7 +139,7 @@ impl<'tcx> ExprVisitor<'tcx> {
template: &[InlineAsmTemplatePiece],
is_input: bool,
tied_input: Option<(&hir::Expr<'tcx>, Option<InlineAsmType>)>,
target_features: &[Symbol],
target_features: &FxHashSet<Symbol>,
) -> Option<InlineAsmType> {
// Check the type against the allowed types for inline asm.
let ty = self.typeck_results.expr_ty_adjusted(expr);
Expand Down Expand Up @@ -285,9 +286,7 @@ impl<'tcx> ExprVisitor<'tcx> {
// (!). In that case we still need the earlier check to verify that the
// register class is usable at all.
if let Some(feature) = feature {
if !self.tcx.sess.target_features.contains(&feature)
&& !target_features.contains(&feature)
{
if !target_features.contains(&feature) {
let msg = &format!("`{}` target feature is not enabled", feature);
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
err.note(&format!(
Expand Down Expand Up @@ -347,7 +346,8 @@ impl<'tcx> ExprVisitor<'tcx> {
let hir = self.tcx.hir();
let enclosing_id = hir.enclosing_body_owner(hir_id);
let enclosing_def_id = hir.local_def_id(enclosing_id).to_def_id();
let attrs = self.tcx.codegen_fn_attrs(enclosing_def_id);
let target_features = self.tcx.asm_target_features(enclosing_def_id);
let asm_arch = self.tcx.sess.asm_arch.unwrap();
for (idx, (op, op_sp)) in asm.operands.iter().enumerate() {
// Validate register classes against currently enabled target
// features. We check that at least one type is available for
Expand All @@ -360,16 +360,29 @@ impl<'tcx> ExprVisitor<'tcx> {
// Note that this is only possible for explicit register
// operands, which cannot be used in the asm string.
if let Some(reg) = op.reg() {
// Some explicit registers cannot be used depending on the
// target. Reject those here.
if let InlineAsmRegOrRegClass::Reg(reg) = reg {
if let Err(msg) = reg.validate(
asm_arch,
self.tcx.sess.relocation_model(),
&target_features,
&self.tcx.sess.target,
op.is_clobber(),
) {
let msg = format!("cannot use register `{}`: {}", reg.name(), msg);
self.tcx.sess.struct_span_err(*op_sp, &msg).emit();
continue;
}
}

if !op.is_clobber() {
let mut missing_required_features = vec![];
let reg_class = reg.reg_class();
for &(_, feature) in reg_class.supported_types(self.tcx.sess.asm_arch.unwrap())
{
for &(_, feature) in reg_class.supported_types(asm_arch) {
match feature {
Some(feature) => {
if self.tcx.sess.target_features.contains(&feature)
|| attrs.target_features.contains(&feature)
{
if target_features.contains(&feature) {
missing_required_features.clear();
break;
} else {
Expand Down Expand Up @@ -425,7 +438,7 @@ impl<'tcx> ExprVisitor<'tcx> {
asm.template,
true,
None,
&attrs.target_features,
&target_features,
);
}
hir::InlineAsmOperand::Out { reg, late: _, ref expr } => {
Expand All @@ -437,7 +450,7 @@ impl<'tcx> ExprVisitor<'tcx> {
asm.template,
false,
None,
&attrs.target_features,
&target_features,
);
}
}
Expand All @@ -449,7 +462,7 @@ impl<'tcx> ExprVisitor<'tcx> {
asm.template,
false,
None,
&attrs.target_features,
&target_features,
);
}
hir::InlineAsmOperand::SplitInOut { reg, late: _, ref in_expr, ref out_expr } => {
Expand All @@ -460,7 +473,7 @@ impl<'tcx> ExprVisitor<'tcx> {
asm.template,
true,
None,
&attrs.target_features,
&target_features,
);
if let Some(out_expr) = out_expr {
self.check_asm_operand_type(
Expand All @@ -470,7 +483,7 @@ impl<'tcx> ExprVisitor<'tcx> {
asm.template,
false,
Some((in_expr, in_ty)),
&attrs.target_features,
&target_features,
);
}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,6 @@ symbols! {
repr_packed,
repr_simd,
repr_transparent,
reserved_r9: "reserved-r9",
residual,
result,
rhs,
Expand Down
15 changes: 8 additions & 7 deletions compiler/rustc_target/src/asm/aarch64.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{InlineAsmArch, InlineAsmType};
use crate::spec::Target;
use crate::spec::{RelocModel, Target};
use rustc_data_structures::stable_set::FxHashSet;
use rustc_macros::HashStable_Generic;
use rustc_span::Symbol;
Expand Down Expand Up @@ -73,17 +73,18 @@ impl AArch64InlineAsmRegClass {
}
}

pub fn reserved_x18(
pub fn target_reserves_x18(target: &Target) -> bool {
target.os == "android" || target.is_like_fuchsia || target.is_like_osx || target.is_like_windows
}

fn reserved_x18(
_arch: InlineAsmArch,
_reloc_model: RelocModel,
_target_features: &FxHashSet<Symbol>,
target: &Target,
_is_clobber: bool,
) -> Result<(), &'static str> {
if target.os == "android"
|| target.is_like_fuchsia
|| target.is_like_osx
|| target.is_like_windows
{
if target_reserves_x18(target) {
Err("x18 is a reserved register on this target")
} else {
Ok(())
Expand Down
Loading