diff options
| author | bors <bors@rust-lang.org> | 2021-07-01 09:20:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-07-01 09:20:38 +0000 |
| commit | 3cb1c1134050c059a15d9ca7a00d4dd89111a373 (patch) | |
| tree | d3e4dd08a2460c57d2904d3a31c9f327025f2680 /compiler | |
| parent | f8ac8fdacf66b351c6479b0c8313e3e57e571ba4 (diff) | |
| parent | d10af08f7234503d53e079d3b0a980b4d8c7b391 (diff) | |
| download | rust-3cb1c1134050c059a15d9ca7a00d4dd89111a373.tar.gz rust-3cb1c1134050c059a15d9ca7a00d4dd89111a373.zip | |
Auto merge of #86774 - GuillaumeGomez:rollup-rkcgvph, r=GuillaumeGomez
Rollup of 6 pull requests Successful merges: - #86558 (Add suggestions for "undefined reference" link errors) - #86616 (rustc_span: Explicitly handle crates that differ from package names) - #86652 (Add support for leaf function frame pointer elimination) - #86666 (Fix misleading "impl Trait" error) - #86762 (mailmap: Add my work email address) - #86773 (Enable the tests developed with #86594) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
27 files changed, 144 insertions, 70 deletions
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 6a032b9be72..56b93f83466 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 <https://sourceware.org/binutils/docs/gprof/Implementation.html>. + 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 7415a570453..f662887abf8 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 22d513d66d1..1fb201eda6b 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/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 6c9ec9e7b0d..d47624da79a 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 diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 31ae84f4ca1..2e9aae467f8 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 6fff64bfcb6..46f2adbe552 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<Vec<Self::Value>>; - 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 d8a58ee18cd..f792e319867 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 <https://sourceware.org/binutils/docs/gprof/Implementation.html>. - 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_span/Cargo.toml b/compiler/rustc_span/Cargo.toml index 08645990c48..4552f14de8b 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" } diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs index feadd4e891c..bf3ec8f9160 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 5682039b865..9fa8ef69d81 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 8a832546d09..a43eb99a1d7 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 2187015b627..586e4043d79 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 cb6c06b3711..934f3370369 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 8530db179d9..0c8a89210ff 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 bef2fce7c83..998d6ffe0fc 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 06d71db4af2..f2635f0656d 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 7002d88c512..92c3a1554ac 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 228976779f0..d95cb6a82d5 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 426df59882d..27a0ac585e3 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 9d9da50be7a..f598f0f38f3 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 145aa4a5894..a332e3b847a 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 0bf89c3f93b..cfdae9623f3 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<Self, ()> { + 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 29b415e7726..70e9e4aed92 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 ec24807fec4..fbe4dd5b501 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 dc7597fe7b2..60fd42970c7 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/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 236fec94bdb..afa4d0f1c4d 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 d6b1e56316b..54aab271fdb 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 = <dyn AstConv<'_>>::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; } |
