diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2018-05-24 12:03:05 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2018-05-24 12:03:05 -0700 |
| commit | f67453729c19b435686c94936d8145051e7f1284 (patch) | |
| tree | 029525400c5744b7251bfaa55b8f04a6449bd5ee /src/librustc_codegen_llvm | |
| parent | a76bff86e6f4b56b2c3fd1704ce8535ed207dd78 (diff) | |
| download | rust-f67453729c19b435686c94936d8145051e7f1284.tar.gz rust-f67453729c19b435686c94936d8145051e7f1284.zip | |
std: Ensure OOM is classified as `nounwind`
OOM can't unwind today, and historically it's been optimized as if it can't unwind. This accidentally regressed with recent changes to the OOM handler, so this commit adds in a codegen test to assert that everything gets optimized away after the OOM function is approrpiately classified as nounwind Closes #50925
Diffstat (limited to 'src/librustc_codegen_llvm')
| -rw-r--r-- | src/librustc_codegen_llvm/attributes.rs | 29 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/callee.rs | 11 |
2 files changed, 24 insertions, 16 deletions
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index b64e102ba78..d6806e7afd3 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -20,7 +20,9 @@ use rustc::ty::TyCtxt; use rustc::ty::maps::Providers; use rustc_data_structures::sync::Lrc; use rustc_data_structures::fx::FxHashMap; +use rustc_target::spec::PanicStrategy; +use attributes; use llvm::{self, Attribute, ValueRef}; use llvm::AttributePlace::Function; use llvm_util; @@ -135,11 +137,28 @@ pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) { Attribute::NoAlias.apply_llfn( llvm::AttributePlace::ReturnValue, llfn); } - if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) { - unwind(llfn, true); - } - if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) { - unwind(llfn, false); + + let can_unwind = if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) { + Some(true) + } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) { + Some(false) + + // Perhaps questionable, but we assume that anything defined + // *in Rust code* may unwind. Foreign items like `extern "C" { + // fn foo(); }` are assumed not to unwind **unless** they have + // a `#[unwind]` attribute. + } else if !cx.tcx.is_foreign_item(id) { + Some(true) + } else { + None + }; + + match can_unwind { + Some(false) => attributes::unwind(llfn, false), + Some(true) if cx.tcx.sess.panic_strategy() == PanicStrategy::Unwind => { + attributes::unwind(llfn, true); + } + Some(true) | None => {} } let features = llvm_target_features(cx.tcx.sess) diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index a3dbc450ce7..2c01bd42cc7 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -26,7 +26,6 @@ use rustc::hir::def_id::DefId; use rustc::ty::{self, TypeFoldable}; use rustc::ty::layout::LayoutOf; use rustc::ty::subst::Substs; -use rustc_target::spec::PanicStrategy; /// Codegens a reference to a fn/method item, monomorphizing and /// inlining as it goes. @@ -102,16 +101,6 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let instance_def_id = instance.def_id(); - // Perhaps questionable, but we assume that anything defined - // *in Rust code* may unwind. Foreign items like `extern "C" { - // fn foo(); }` are assumed not to unwind **unless** they have - // a `#[unwind]` attribute. - if tcx.sess.panic_strategy() == PanicStrategy::Unwind { - if !tcx.is_foreign_item(instance_def_id) { - attributes::unwind(llfn, true); - } - } - // Apply an appropriate linkage/visibility value to our item that we // just declared. // |
