about summary refs log tree commit diff
path: root/src/librustc_codegen_llvm
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2018-05-24 12:03:05 -0700
committerAlex Crichton <alex@alexcrichton.com>2018-05-24 12:03:05 -0700
commitf67453729c19b435686c94936d8145051e7f1284 (patch)
tree029525400c5744b7251bfaa55b8f04a6449bd5ee /src/librustc_codegen_llvm
parenta76bff86e6f4b56b2c3fd1704ce8535ed207dd78 (diff)
downloadrust-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.rs29
-rw-r--r--src/librustc_codegen_llvm/callee.rs11
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.
         //