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 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/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 diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 31ae84f4ca11d..2e9aae467f874 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_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" } 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/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/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 \ 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: } 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")) 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`.