From ab0f63ecdf03a0d058eb93fefc3103544f02fee6 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 24 Jun 2021 23:48:53 -0700 Subject: [PATCH 1/7] rustc_span: Explicitly handle crates that differ from package names The sha-1 and md-5 packages contain crates named sha1 and md5, respectively. This discrepancy makes it somewhat more challenging to automate detection of unused crates. Explicitly rename the packages to the names of the crates they contain, to simplify such detection. --- compiler/rustc_span/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml index 08645990c4870..4552f14de8b70 100644 --- a/compiler/rustc_span/Cargo.toml +++ b/compiler/rustc_span/Cargo.toml @@ -17,6 +17,6 @@ scoped-tls = "1.0" unicode-width = "0.1.4" cfg-if = "0.1.2" tracing = "0.1" -sha-1 = "0.9" +sha1 = { package = "sha-1", version = "0.9" } sha2 = "0.9" -md-5 = "0.9" +md5 = { package = "md-5", version = "0.9" } From 61554bc9d72472332aac8cad341d77aa40cfb733 Mon Sep 17 00:00:00 2001 From: Paul Trojahn Date: Fri, 25 Jun 2021 18:22:32 +0200 Subject: [PATCH 2/7] Fix misleading "impl Trait" error Closes #84160 --- compiler/rustc_typeck/src/check/coercion.rs | 1 + .../src/check/fn_ctxt/suggestions.rs | 16 +++++++++++++--- .../ui/extern/extern-types-distinct-types.stderr | 2 ++ src/test/ui/retslot-cast.stderr | 3 +++ src/test/ui/typeck/issue-84160.rs | 9 +++++++++ src/test/ui/typeck/issue-84160.stderr | 15 +++++++++++++++ 6 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/typeck/issue-84160.rs create mode 100644 src/test/ui/typeck/issue-84160.stderr diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 236fec94bdba7..afa4d0f1c4de9 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1481,6 +1481,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { expected, found, can_suggest, + fcx.tcx.hir().get_parent_item(id), ); } if !pointing_at_return_type { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index d6b1e56316b37..54aab271fdb3c 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -52,9 +52,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut pointing_at_return_type = false; if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) { - pointing_at_return_type = - self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest); let fn_id = self.tcx.hir().get_return_block(blk_id).unwrap(); + pointing_at_return_type = self.suggest_missing_return_type( + err, + &fn_decl, + expected, + found, + can_suggest, + fn_id, + ); self.suggest_missing_break_or_return_expr( err, expr, &fn_decl, expected, found, blk_id, fn_id, ); @@ -433,6 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, found: Ty<'tcx>, can_suggest: bool, + fn_id: hir::HirId, ) -> bool { // Only suggest changing the return type for methods that // haven't set a return type at all (and aren't `fn main()` or an impl). @@ -465,7 +472,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = >::ast_ty_to_ty(self, ty); debug!("suggest_missing_return_type: return type {:?}", ty); debug!("suggest_missing_return_type: expected type {:?}", ty); - if ty.kind() == expected.kind() { + let bound_vars = self.tcx.late_bound_vars(fn_id); + let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars)); + let ty = self.normalize_associated_types_in(sp, ty); + if self.can_coerce(expected, ty) { err.span_label(sp, format!("expected `{}` because of return type", expected)); return true; } diff --git a/src/test/ui/extern/extern-types-distinct-types.stderr b/src/test/ui/extern/extern-types-distinct-types.stderr index 32b45ee10ad6f..f69629232aed1 100644 --- a/src/test/ui/extern/extern-types-distinct-types.stderr +++ b/src/test/ui/extern/extern-types-distinct-types.stderr @@ -6,6 +6,8 @@ LL | type A; LL | type B; | ------- the expected foreign type ... +LL | fn foo(r: &A) -> &B { + | -- expected `&B` because of return type LL | r | ^ expected extern type `B`, found extern type `A` | diff --git a/src/test/ui/retslot-cast.stderr b/src/test/ui/retslot-cast.stderr index 9b5f11ce66765..798ce1199a9dc 100644 --- a/src/test/ui/retslot-cast.stderr +++ b/src/test/ui/retslot-cast.stderr @@ -1,6 +1,9 @@ error[E0308]: mismatched types --> $DIR/retslot-cast.rs:13:5 | +LL | -> Option<&Iterator> { + | -------------------------- expected `Option<&dyn Iterator>` because of return type +... LL | inner(x) | ^^^^^^^^ expected trait `Iterator`, found trait `Iterator + Send` | diff --git a/src/test/ui/typeck/issue-84160.rs b/src/test/ui/typeck/issue-84160.rs new file mode 100644 index 0000000000000..7b444df85282a --- /dev/null +++ b/src/test/ui/typeck/issue-84160.rs @@ -0,0 +1,9 @@ +fn mismatched_types_with_reference(x: &u32) -> &u32 { + if false { + return x; + } + return "test"; + //~^ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-84160.stderr b/src/test/ui/typeck/issue-84160.stderr new file mode 100644 index 0000000000000..24c188b3fcb70 --- /dev/null +++ b/src/test/ui/typeck/issue-84160.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/issue-84160.rs:5:12 + | +LL | fn mismatched_types_with_reference(x: &u32) -> &u32 { + | ---- expected `&u32` because of return type +... +LL | return "test"; + | ^^^^^^ expected `u32`, found `str` + | + = note: expected reference `&u32` + found reference `&'static str` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 9b67cba4f6294e0db900397cdf5c59c1dc901ade Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 26 Jun 2021 23:53:35 +0300 Subject: [PATCH 3/7] Add support for leaf fn frame pointer elimination MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds ability for the target specifications to specify frame pointer emission type that's not just “always” or “whatever cg decides”. In particular there's a new mode that allows omission of the frame pointer for leaf functions (those that don't call any other functions). We then set this new mode for Aarch64-based Apple targets. Fixes #86196 --- compiler/rustc_codegen_llvm/src/attributes.rs | 30 ++++++---- compiler/rustc_codegen_llvm/src/context.rs | 4 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- compiler/rustc_codegen_ssa/src/base.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/misc.rs | 2 +- compiler/rustc_session/src/session.rs | 12 ---- .../src/spec/aarch64_apple_darwin.rs | 8 ++- .../src/spec/aarch64_apple_ios.rs | 3 +- .../src/spec/aarch64_apple_ios_macabi.rs | 3 +- .../src/spec/aarch64_apple_ios_sim.rs | 3 +- .../src/spec/aarch64_apple_tvos.rs | 3 +- compiler/rustc_target/src/spec/apple_base.rs | 4 +- .../rustc_target/src/spec/freebsd_base.rs | 4 +- .../src/spec/i686_apple_darwin.rs | 4 +- .../src/spec/i686_pc_windows_gnu.rs | 4 +- .../src/spec/i686_unknown_linux_musl.rs | 4 +- .../src/spec/i686_uwp_windows_gnu.rs | 4 +- .../rustc_target/src/spec/illumos_base.rs | 4 +- .../src/spec/linux_kernel_base.rs | 5 +- compiler/rustc_target/src/spec/mod.rs | 55 +++++++++++++++++-- .../rustc_target/src/spec/openbsd_base.rs | 4 +- compiler/rustc_target/src/spec/thumb_base.rs | 5 +- .../src/spec/x86_64_apple_darwin.rs | 5 +- src/test/codegen/frame-pointer.rs | 35 ++++++++++++ 24 files changed, 149 insertions(+), 60 deletions(-) create mode 100644 src/test/codegen/frame-pointer.rs diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 6a032b9be723b..56b93f8346680 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -12,7 +12,7 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::OptLevel; use rustc_session::Session; use rustc_target::spec::abi::Abi; -use rustc_target::spec::{SanitizerSet, StackProbeType}; +use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType}; use crate::attributes; use crate::llvm::AttributePlace::Function; @@ -69,15 +69,25 @@ fn naked(val: &'ll Value, is_naked: bool) { Attribute::Naked.toggle_llfn(Function, val, is_naked); } -pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { - if cx.sess().must_not_eliminate_frame_pointers() { - llvm::AddFunctionAttrStringValue( - llfn, - llvm::AttributePlace::Function, - cstr!("frame-pointer"), - cstr!("all"), - ); +pub fn set_frame_pointer_type(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { + let mut fp = cx.sess().target.frame_pointer; + // "mcount" function relies on stack pointer. + // See . + if cx.sess().instrument_mcount() || matches!(cx.sess().opts.cg.force_frame_pointers, Some(true)) + { + fp = FramePointer::Always; } + let attr_value = match fp { + FramePointer::Always => cstr!("all"), + FramePointer::NonLeaf => cstr!("non-leaf"), + FramePointer::MayOmit => return, + }; + llvm::AddFunctionAttrStringValue( + llfn, + llvm::AttributePlace::Function, + cstr!("frame-pointer"), + attr_value, + ); } /// Tell LLVM what instrument function to insert. @@ -254,7 +264,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: } // FIXME: none of these three functions interact with source level attributes. - set_frame_pointer_elimination(cx, llfn); + set_frame_pointer_type(cx, llfn); set_instrument_function(cx, llfn); set_probestack(cx, llfn); diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 7415a57045336..f662887abf820 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -410,8 +410,8 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { &self.used_statics } - fn set_frame_pointer_elimination(&self, llfn: &'ll Value) { - attributes::set_frame_pointer_elimination(self, llfn) + fn set_frame_pointer_type(&self, llfn: &'ll Value) { + attributes::set_frame_pointer_type(self, llfn) } fn apply_target_cpu_attr(&self, llfn: &'ll Value) { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 22d513d66d1cc..1fb201eda6bb0 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -674,7 +674,7 @@ fn gen_fn<'ll, 'tcx>( ) -> &'ll Value { let fn_abi = FnAbi::of_fn_ptr(cx, rust_fn_sig, &[]); let llfn = cx.declare_fn(name, &fn_abi); - cx.set_frame_pointer_elimination(llfn); + cx.set_frame_pointer_type(llfn); cx.apply_target_cpu_attr(llfn); // FIXME(eddyb) find a nicer way to do this. unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::InternalLinkage) }; diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 38ab39febe066..9e1e4c0c817fd 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -406,7 +406,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( }; // `main` should respect same config for frame pointer elimination as rest of code - cx.set_frame_pointer_elimination(llfn); + cx.set_frame_pointer_type(llfn); cx.apply_target_cpu_attr(llfn); let llbb = Bx::append_block(&cx, llfn, "top"); diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index 6fff64bfcb6c5..46f2adbe55209 100644 --- a/compiler/rustc_codegen_ssa/src/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs @@ -16,7 +16,7 @@ pub trait MiscMethods<'tcx>: BackendTypes { fn sess(&self) -> &Session; fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx>; fn used_statics(&self) -> &RefCell>; - fn set_frame_pointer_elimination(&self, llfn: Self::Function); + fn set_frame_pointer_type(&self, llfn: Self::Function); fn apply_target_cpu_attr(&self, llfn: Self::Function); fn create_used_variable(&self); /// Declares the extern "C" main function for the entry point. Returns None if the symbol already exists. diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index d8a58ee18cd8e..f792e31986779 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -792,18 +792,6 @@ impl Session { !self.target.is_like_windows && !self.target.is_like_osx } - pub fn must_not_eliminate_frame_pointers(&self) -> bool { - // "mcount" function relies on stack pointer. - // See . - if self.instrument_mcount() { - true - } else if let Some(x) = self.opts.cg.force_frame_pointers { - x - } else { - !self.target.eliminate_frame_pointer - } - } - pub fn must_emit_unwind_tables(&self) -> bool { // This is used to control the emission of the `uwtable` attribute on // LLVM functions. diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs index feadd4e891cec..bf3ec8f9160b0 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, SanitizerSet, Target, TargetOptions}; +use crate::spec::{FramePointer, LinkerFlavor, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::apple_base::opts("macos"); @@ -20,6 +20,10 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".to_string(), arch: arch.to_string(), - options: TargetOptions { mcount: "\u{1}mcount".to_string(), ..base }, + options: TargetOptions { + mcount: "\u{1}mcount".to_string(), + frame_pointer: FramePointer::NonLeaf, + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs index 5682039b86512..9fa8ef69d8131 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs @@ -1,5 +1,5 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { let base = opts("ios", Arch::Arm64); @@ -13,6 +13,7 @@ pub fn target() -> Target { max_atomic_width: Some(128), unsupported_abis: super::arm_base::unsupported_abis(), forces_embed_bitcode: true, + frame_pointer: FramePointer::NonLeaf, // Taken from a clang build on Xcode 11.4.1. // These arguments are not actually invoked - they just have // to look right to pass App Store validation. diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs index 8a832546d0952..a43eb99a1d73f 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs @@ -1,5 +1,5 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { let base = opts("ios", Arch::Arm64_macabi); @@ -13,6 +13,7 @@ pub fn target() -> Target { max_atomic_width: Some(128), unsupported_abis: super::arm_base::unsupported_abis(), forces_embed_bitcode: true, + frame_pointer: FramePointer::NonLeaf, // Taken from a clang build on Xcode 11.4.1. // These arguments are not actually invoked - they just have // to look right to pass App Store validation. diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs index 2187015b627d3..586e4043d79de 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs @@ -1,5 +1,5 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { let base = opts("ios", Arch::Arm64_sim); @@ -21,6 +21,7 @@ pub fn target() -> Target { max_atomic_width: Some(128), unsupported_abis: super::arm_base::unsupported_abis(), forces_embed_bitcode: true, + frame_pointer: FramePointer::NonLeaf, // Taken from a clang build on Xcode 11.4.1. // These arguments are not actually invoked - they just have // to look right to pass App Store validation. diff --git a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs index cb6c06b371183..934f33703690f 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs @@ -1,5 +1,5 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { let base = opts("tvos", Arch::Arm64); @@ -13,6 +13,7 @@ pub fn target() -> Target { max_atomic_width: Some(128), unsupported_abis: super::arm_base::unsupported_abis(), forces_embed_bitcode: true, + frame_pointer: FramePointer::NonLeaf, ..base }, } diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 8530db179d991..0c8a89210ffcd 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -1,6 +1,6 @@ use std::env; -use crate::spec::{SplitDebuginfo, TargetOptions}; +use crate::spec::{FramePointer, SplitDebuginfo, TargetOptions}; pub fn opts(os: &str) -> TargetOptions { // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6 @@ -27,7 +27,7 @@ pub fn opts(os: &str) -> TargetOptions { families: vec!["unix".to_string()], is_like_osx: true, dwarf_version: Some(2), - eliminate_frame_pointer: false, + frame_pointer: FramePointer::Always, has_rpath: true, dll_suffix: ".dylib".to_string(), archive_format: "darwin".to_string(), diff --git a/compiler/rustc_target/src/spec/freebsd_base.rs b/compiler/rustc_target/src/spec/freebsd_base.rs index bef2fce7c839b..998d6ffe0fc66 100644 --- a/compiler/rustc_target/src/spec/freebsd_base.rs +++ b/compiler/rustc_target/src/spec/freebsd_base.rs @@ -1,4 +1,4 @@ -use crate::spec::{RelroLevel, TargetOptions}; +use crate::spec::{FramePointer, RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { TargetOptions { @@ -8,7 +8,7 @@ pub fn opts() -> TargetOptions { families: vec!["unix".to_string()], has_rpath: true, position_independent_executables: true, - eliminate_frame_pointer: false, // FIXME 43575 + frame_pointer: FramePointer::Always, // FIXME 43575: should be MayOmit... relro_level: RelroLevel::Full, abi_return_struct_as_int: true, dwarf_version: Some(2), diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs index 06d71db4af241..f2635f0656d7a 100644 --- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{FramePointer, LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::apple_base::opts("macos"); @@ -8,7 +8,7 @@ pub fn target() -> Target { base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved base.stack_probes = StackProbeType::Call; - base.eliminate_frame_pointer = false; + base.frame_pointer = FramePointer::Always; // Clang automatically chooses a more specific target based on // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work diff --git a/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs index 7002d88c512d7..92c3a1554ac54 100644 --- a/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, Target}; +use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, Target}; pub fn target() -> Target { let mut base = super::windows_gnu_base::opts(); @@ -6,7 +6,7 @@ pub fn target() -> Target { base.pre_link_args .insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".to_string(), "i386pe".to_string()]); base.max_atomic_width = Some(64); - base.eliminate_frame_pointer = false; // Required for backtraces + base.frame_pointer = FramePointer::Always; // Required for backtraces base.linker = Some("i686-w64-mingw32-gcc".to_string()); // Mark all dynamic libraries and executables as compatible with the larger 4GiB address diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs index 228976779f0d4..d95cb6a82d558 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{FramePointer, LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); @@ -21,7 +21,7 @@ pub fn target() -> Target { // // This may or may not be related to this bug: // https://llvm.org/bugs/show_bug.cgi?id=30879 - base.eliminate_frame_pointer = false; + base.frame_pointer = FramePointer::Always; Target { llvm_target: "i686-unknown-linux-musl".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs index 426df59882d58..27a0ac585e391 100644 --- a/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, Target}; +use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, Target}; pub fn target() -> Target { let mut base = super::windows_uwp_gnu_base::opts(); @@ -6,7 +6,7 @@ pub fn target() -> Target { base.pre_link_args .insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".to_string(), "i386pe".to_string()]); base.max_atomic_width = Some(64); - base.eliminate_frame_pointer = false; // Required for backtraces + base.frame_pointer = FramePointer::Always; // Required for backtraces // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. diff --git a/compiler/rustc_target/src/spec/illumos_base.rs b/compiler/rustc_target/src/spec/illumos_base.rs index 9d9da50be7a27..f598f0f38f305 100644 --- a/compiler/rustc_target/src/spec/illumos_base.rs +++ b/compiler/rustc_target/src/spec/illumos_base.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{FramePointer, LinkArgs, LinkerFlavor, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { @@ -35,7 +35,7 @@ pub fn opts() -> TargetOptions { is_like_solaris: true, linker_is_gnu: false, limit_rdylib_exports: false, // Linker doesn't support this - eliminate_frame_pointer: false, + frame_pointer: FramePointer::Always, eh_frame_header: false, late_link_args, diff --git a/compiler/rustc_target/src/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs index 145aa4a589443..a332e3b847a29 100644 --- a/compiler/rustc_target/src/spec/linux_kernel_base.rs +++ b/compiler/rustc_target/src/spec/linux_kernel_base.rs @@ -1,4 +1,5 @@ -use crate::spec::{PanicStrategy, RelocModel, RelroLevel, StackProbeType, TargetOptions}; +use crate::spec::TargetOptions; +use crate::spec::{FramePointer, PanicStrategy, RelocModel, RelroLevel, StackProbeType}; pub fn opts() -> TargetOptions { TargetOptions { @@ -7,7 +8,7 @@ pub fn opts() -> TargetOptions { panic_strategy: PanicStrategy::Abort, // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved stack_probes: StackProbeType::Call, - eliminate_frame_pointer: false, + frame_pointer: FramePointer::Always, position_independent_executables: true, needs_plt: true, relro_level: RelroLevel::Full, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 0bf89c3f93b99..cfdae9623f34a 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -671,6 +671,42 @@ impl ToJson for SanitizerSet { } } +#[derive(Clone, Copy, PartialEq, Hash, Debug)] +pub enum FramePointer { + /// Forces the machine code generator to always preserve the frame pointers. + Always, + /// Forces the machine code generator to preserve the frame pointers except for the leaf + /// functions (i.e. those that don't call other functions). + NonLeaf, + /// Allows the machine code generator to omit the frame pointers. + /// + /// This option does not guarantee that the frame pointers will be omitted. + MayOmit, +} + +impl FromStr for FramePointer { + type Err = (); + fn from_str(s: &str) -> Result { + Ok(match s { + "always" => Self::Always, + "non-leaf" => Self::NonLeaf, + "may-omit" => Self::MayOmit, + _ => return Err(()), + }) + } +} + +impl ToJson for FramePointer { + fn to_json(&self) -> Json { + match *self { + Self::Always => "always", + Self::NonLeaf => "non-leaf", + Self::MayOmit => "may-omit", + } + .to_json() + } +} + macro_rules! supported_targets { ( $(($( $triple:literal, )+ $module:ident ),)+ ) => { $(mod $module;)+ @@ -1068,8 +1104,8 @@ pub struct TargetOptions { pub tls_model: TlsModel, /// Do not emit code that uses the "red zone", if the ABI has one. Defaults to false. pub disable_redzone: bool, - /// Eliminate frame pointers from stack frames if possible. Defaults to true. - pub eliminate_frame_pointer: bool, + /// Frame pointer mode for this target. Defaults to `MayOmit`. + pub frame_pointer: FramePointer, /// Emit each function in its own section. Defaults to true. pub function_sections: bool, /// String to prepend to the name of every dynamic library. Defaults to "lib". @@ -1330,7 +1366,7 @@ impl Default for TargetOptions { code_model: None, tls_model: TlsModel::GeneralDynamic, disable_redzone: false, - eliminate_frame_pointer: true, + frame_pointer: FramePointer::MayOmit, function_sections: true, dll_prefix: "lib".to_string(), dll_suffix: ".so".to_string(), @@ -1833,6 +1869,16 @@ impl Target { } } + if let Some(fp) = obj.remove_key("frame-pointer") { + if let Some(s) = Json::as_string(&fp) { + base.frame_pointer = s + .parse() + .map_err(|()| format!("'{}' is not a valid value for frame-pointer", s))?; + } else { + incorrect_type.push("frame-pointer".to_string()) + } + } + key!(is_builtin, bool); key!(c_int_width = "target-c-int-width"); key!(os); @@ -1864,7 +1910,6 @@ impl Target { key!(code_model, CodeModel)?; key!(tls_model, TlsModel)?; key!(disable_redzone, bool); - key!(eliminate_frame_pointer, bool); key!(function_sections, bool); key!(dll_prefix); key!(dll_suffix); @@ -2128,7 +2173,7 @@ impl ToJson for Target { target_option_val!(code_model); target_option_val!(tls_model); target_option_val!(disable_redzone); - target_option_val!(eliminate_frame_pointer); + target_option_val!(frame_pointer); target_option_val!(function_sections); target_option_val!(dll_prefix); target_option_val!(dll_suffix); diff --git a/compiler/rustc_target/src/spec/openbsd_base.rs b/compiler/rustc_target/src/spec/openbsd_base.rs index 29b415e77266e..70e9e4aed9249 100644 --- a/compiler/rustc_target/src/spec/openbsd_base.rs +++ b/compiler/rustc_target/src/spec/openbsd_base.rs @@ -1,4 +1,4 @@ -use crate::spec::{RelroLevel, TargetOptions}; +use crate::spec::{FramePointer, RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { TargetOptions { @@ -9,7 +9,7 @@ pub fn opts() -> TargetOptions { has_rpath: true, abi_return_struct_as_int: true, position_independent_executables: true, - eliminate_frame_pointer: false, // FIXME 43575 + frame_pointer: FramePointer::Always, // FIXME 43575: should be MayOmit... relro_level: RelroLevel::Full, dwarf_version: Some(2), ..Default::default() diff --git a/compiler/rustc_target/src/spec/thumb_base.rs b/compiler/rustc_target/src/spec/thumb_base.rs index ec24807fec4ea..fbe4dd5b50180 100644 --- a/compiler/rustc_target/src/spec/thumb_base.rs +++ b/compiler/rustc_target/src/spec/thumb_base.rs @@ -27,7 +27,8 @@ // differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of // build scripts / gcc flags. -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions}; +use crate::spec::TargetOptions; +use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; pub fn opts() -> TargetOptions { // See rust-lang/rfcs#1645 for a discussion about these defaults @@ -52,7 +53,7 @@ pub fn opts() -> TargetOptions { emit_debug_gdb_scripts: false, // LLVM is eager to trash the link register when calling `noreturn` functions, which // breaks debugging. Preserve LR by default to prevent that from happening. - eliminate_frame_pointer: false, + frame_pointer: FramePointer::Always, ..Default::default() } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs index dc7597fe7b2a1..60fd42970c7d6 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs @@ -1,10 +1,11 @@ -use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target, TargetOptions}; +use crate::spec::TargetOptions; +use crate::spec::{FramePointer, LinkerFlavor, SanitizerSet, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::apple_base::opts("macos"); base.cpu = "core2".to_string(); base.max_atomic_width = Some(128); // core2 support cmpxchg16b - base.eliminate_frame_pointer = false; + base.frame_pointer = FramePointer::Always; base.pre_link_args.insert( LinkerFlavor::Gcc, vec!["-m64".to_string(), "-arch".to_string(), "x86_64".to_string()], diff --git a/src/test/codegen/frame-pointer.rs b/src/test/codegen/frame-pointer.rs new file mode 100644 index 0000000000000..367591dcb9617 --- /dev/null +++ b/src/test/codegen/frame-pointer.rs @@ -0,0 +1,35 @@ +// compile-flags: --crate-type=rlib +// revisions: aarch64-apple aarch64-linux force x64-apple x64-linux +// [aarch64-apple] needs-llvm-components: aarch64 +// [aarch64-apple] compile-flags: --target=aarch64-apple-darwin +// [aarch64-linux] needs-llvm-components: aarch64 +// [aarch64-linux] compile-flags: --target=aarch64-unknown-linux-gnu +// [force] needs-llvm-components: x86 +// [force] compile-flags: --target=x86_64-unknown-linux-gnu -Cforce-frame-pointers=yes +// [x64-apple] needs-llvm-components: x86 +// [x64-apple] compile-flags: --target=x86_64-apple-darwin +// [x64-linux] needs-llvm-components: x86 +// [x64-linux] compile-flags: --target=x86_64-unknown-linux-gnu + +#![feature(no_core, lang_items)] +#![no_core] +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } + + + +// CHECK: define i32 @peach{{.*}}[[PEACH_ATTRS:\#[0-9]+]] { +#[no_mangle] +pub fn peach(x: u32) -> u32 { + x +} + +// CHECK: attributes [[PEACH_ATTRS]] = { +// x64-linux-NOT: {{.*}}"frame-pointer"{{.*}} +// aarch64-linux-NOT: {{.*}}"frame-pointer"{{.*}} +// x64-apple-SAME: {{.*}}"frame-pointer"="all" +// force-SAME: {{.*}}"frame-pointer"="all" +// aarch64-apple-SAME: {{.*}}"frame-pointer"="non-leaf" +// CHECK-SAME: } From ce63d55bc7d1a1cd65d175e22787ea964bba0e2a Mon Sep 17 00:00:00 2001 From: Smitty Date: Tue, 22 Jun 2021 17:46:34 -0400 Subject: [PATCH 4/7] Add suggestions for "undefined reference" link errors --- compiler/rustc_codegen_ssa/src/back/link.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 6c9ec9e7b0dae..d47624da79a73 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -912,14 +912,23 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); - sess.struct_err(&format!( + let escaped_output = escape_stdout_stderr_string(&output); + let mut err = sess.struct_err(&format!( "linking with `{}` failed: {}", linker_path.display(), prog.status - )) - .note(&format!("{:?}", &cmd)) - .note(&escape_stdout_stderr_string(&output)) - .emit(); + )); + err.note(&format!("{:?}", &cmd)).note(&escaped_output); + if escaped_output.contains("undefined reference to") { + err.help( + "some `extern` functions couldn't be found; some native libraries may \ + need to be installed or have their path specified", + ); + err.note("use the `-l` flag to specify native libraries to link"); + err.note("use the `cargo:rustc-link-lib` directive to specify the native \ + libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)"); + } + err.emit(); // If MSVC's `link.exe` was expected but the return code // is not a Microsoft LNK error then suggest a way to fix or From 2edf955904d30a682ba90c57de89231deb320b78 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 1 Jul 2021 07:37:31 +0900 Subject: [PATCH 5/7] mailmap: Add my work email address --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 8cb74824d939a..113feb3a8f58a 100644 --- a/.mailmap +++ b/.mailmap @@ -290,6 +290,7 @@ Xuefeng Wu XuefengWu York Xiang Youngsoo Son Yuki Okushi +Yuki Okushi Zach Pomerantz Zack Corr Zack Slayton From 36458510878345ba38b37de7f92b885c54af0322 Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Thu, 1 Jul 2021 10:13:28 +0200 Subject: [PATCH 6/7] Enable the tests developed with #86594 --- src/test/rustdoc-gui/label-next-to-symbol.goml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/rustdoc-gui/label-next-to-symbol.goml b/src/test/rustdoc-gui/label-next-to-symbol.goml index 827e4b97a0aa3..4fef4e655fdfb 100644 --- a/src/test/rustdoc-gui/label-next-to-symbol.goml +++ b/src/test/rustdoc-gui/label-next-to-symbol.goml @@ -13,12 +13,12 @@ assert-css: (".item-table .item-left .stab.portability", { "background-color": " // table like view assert-css: (".item-right.docblock-short", { "padding-left": "0px" }) -// Requires new function: https://github.com/GuillaumeGomez/browser-UI-test/pull/202 -//compare-elements-position-near: ("//*[@class='item-left module-item']//a[text()='replaced_function']", ".item-left .stab.deprecated", ("y")) +compare-elements-position-near: ("//*[@class='item-left module-item']//a[text()='replaced_function']", ".item-left .stab.deprecated", {"y": 2}) compare-elements-position: (".item-left .stab.deprecated", ".item-left .stab.portability", ("y")) // Ensure no wrap -//compare-elements-position: ("//*[@class='item-left module-item']//a[text()='replaced_function']", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']", ("y")) +compare-elements-position-near: ("//*[@class='item-left module-item']//a[text()='replaced_function']", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']", {"y": 2}) +// compare parent elements compare-elements-position: ("//*[@class='item-left module-item']//a[text()='replaced_function']/..", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']/..", ("y")) @@ -26,11 +26,11 @@ compare-elements-position: ("//*[@class='item-left module-item']//a[text()='repl size: (600, 600) // staggered layout with 2em spacing assert-css: (".item-right.docblock-short", { "padding-left": "32px" }) -// Requires new function: https://github.com/GuillaumeGomez/browser-UI-test/pull/202 -//compare-elements-position-near: ("//*[@class='item-left module-item']//a[text()='replaced_function']", ".item-left .stab.deprecated", ("y")) +compare-elements-position-near: ("//*[@class='item-left module-item']//a[text()='replaced_function']", ".item-left .stab.deprecated", {"y": 1}) compare-elements-position: (".item-left .stab.deprecated", ".item-left .stab.portability", ("y")) // Ensure wrap -compare-elements-position-false: ("//*[@class='item-left module-item']//a[text()='replaced_function']", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']", ("y")) +compare-elements-position-near-false: ("//*[@class='item-left module-item']//a[text()='replaced_function']", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']", {"y": 12}) +// compare parent elements compare-elements-position-false: ("//*[@class='item-left module-item']//a[text()='replaced_function']/..", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']/..", ("y")) compare-elements-position-false: (".item-left .stab.deprecated", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']", ("y")) From dbfbb76ba4dca60cb5a61494234272b98f7165fc Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Thu, 1 Jul 2021 10:22:03 +0200 Subject: [PATCH 7/7] Update container browser-ui-test@0.4.1 --- src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile index faed1761fa45c..6dcf0bdcba43f 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile @@ -72,7 +72,7 @@ ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}" # https://github.com/puppeteer/puppeteer/issues/375 # # We also specify the version in case we need to update it to go around cache limitations. -RUN npm install -g browser-ui-test@0.4.0 --unsafe-perm=true +RUN npm install -g browser-ui-test@0.4.1 --unsafe-perm=true ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \