Skip to content

Commit b4247d4

Browse files
committed
Auto merge of #51041 - alexcrichton:better-unwind, r=nikomatsakis
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
2 parents 444a9c3 + f674537 commit b4247d4

File tree

4 files changed

+46
-16
lines changed

4 files changed

+46
-16
lines changed

src/liballoc/alloc.rs

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
133133
}
134134
}
135135

136+
#[rustc_allocator_nounwind]
136137
pub fn oom() -> ! {
137138
extern {
138139
#[lang = "oom"]

src/librustc_codegen_llvm/attributes.rs

+24-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ use rustc::ty::TyCtxt;
2020
use rustc::ty::maps::Providers;
2121
use rustc_data_structures::sync::Lrc;
2222
use rustc_data_structures::fx::FxHashMap;
23+
use rustc_target::spec::PanicStrategy;
2324

25+
use attributes;
2426
use llvm::{self, Attribute, ValueRef};
2527
use llvm::AttributePlace::Function;
2628
use llvm_util;
@@ -135,11 +137,28 @@ pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) {
135137
Attribute::NoAlias.apply_llfn(
136138
llvm::AttributePlace::ReturnValue, llfn);
137139
}
138-
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) {
139-
unwind(llfn, true);
140-
}
141-
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
142-
unwind(llfn, false);
140+
141+
let can_unwind = if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) {
142+
Some(true)
143+
} else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
144+
Some(false)
145+
146+
// Perhaps questionable, but we assume that anything defined
147+
// *in Rust code* may unwind. Foreign items like `extern "C" {
148+
// fn foo(); }` are assumed not to unwind **unless** they have
149+
// a `#[unwind]` attribute.
150+
} else if !cx.tcx.is_foreign_item(id) {
151+
Some(true)
152+
} else {
153+
None
154+
};
155+
156+
match can_unwind {
157+
Some(false) => attributes::unwind(llfn, false),
158+
Some(true) if cx.tcx.sess.panic_strategy() == PanicStrategy::Unwind => {
159+
attributes::unwind(llfn, true);
160+
}
161+
Some(true) | None => {}
143162
}
144163

145164
let features = llvm_target_features(cx.tcx.sess)

src/librustc_codegen_llvm/callee.rs

-11
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use rustc::hir::def_id::DefId;
2626
use rustc::ty::{self, TypeFoldable};
2727
use rustc::ty::layout::LayoutOf;
2828
use rustc::ty::subst::Substs;
29-
use rustc_target::spec::PanicStrategy;
3029

3130
/// Codegens a reference to a fn/method item, monomorphizing and
3231
/// inlining as it goes.
@@ -102,16 +101,6 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
102101

103102
let instance_def_id = instance.def_id();
104103

105-
// Perhaps questionable, but we assume that anything defined
106-
// *in Rust code* may unwind. Foreign items like `extern "C" {
107-
// fn foo(); }` are assumed not to unwind **unless** they have
108-
// a `#[unwind]` attribute.
109-
if tcx.sess.panic_strategy() == PanicStrategy::Unwind {
110-
if !tcx.is_foreign_item(instance_def_id) {
111-
attributes::unwind(llfn, true);
112-
}
113-
}
114-
115104
// Apply an appropriate linkage/visibility value to our item that we
116105
// just declared.
117106
//
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// no-system-llvm
12+
// compile-flags: -O
13+
#![crate_type="lib"]
14+
15+
#[no_mangle]
16+
pub fn get_len() -> usize {
17+
// CHECK-LABEL: @get_len
18+
// CHECK-NOT: call
19+
// CHECK-NOT: invoke
20+
[1, 2, 3].iter().collect::<Vec<_>>().len()
21+
}

0 commit comments

Comments
 (0)