Skip to content

Commit

Permalink
Mark functions returning uninhabited types as noreturn
Browse files Browse the repository at this point in the history
  • Loading branch information
nox committed Apr 28, 2018
1 parent ff65726 commit 69ec4aa
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/librustc_trans/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
}
None => {}
};
if sig.output().is_never() {
if cx.layout_of(sig.output()).abi == ty::layout::Abi::Uninhabited {
flags = flags | DIFlags::FlagNoReturn;
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use llvm::{self, ValueRef};
use llvm::AttributePlace::Function;
use rustc::ty::{self, Ty};
use rustc::ty::layout::{self, LayoutOf};
use rustc::session::config::Sanitizer;
use rustc_target::spec::PanicStrategy;
use abi::{Abi, FnType, FnTypeExt};
Expand Down Expand Up @@ -133,8 +134,7 @@ pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str,
let fty = FnType::new(cx, sig, &[]);
let llfn = declare_raw_fn(cx, name, fty.llvm_cconv(), fty.llvm_type(cx));

// FIXME(canndrew): This is_never should really be an is_uninhabited
if sig.output().is_never() {
if cx.layout_of(sig.output()).abi == layout::Abi::Uninhabited {
llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
}

Expand Down
22 changes: 16 additions & 6 deletions src/test/codegen/noreturnflag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,27 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -g -C no-prepopulate-passes
// ignore-tidy-linelength
// min-llvm-version 4.0

// compile-flags: -g -C no-prepopulate-passes

// CHECK: {{.*}}DISubprogram{{.*}}name: "foo"{{.*}}DIFlagNoReturn
#![crate_type = "lib"]

fn foo() -> ! {
#[no_mangle]
pub fn foo() -> ! {
// CHECK: @foo() unnamed_addr #0
loop {}
}

pub fn main() {
foo();
pub enum EmptyEnum {}

#[no_mangle]
pub fn bar() -> EmptyEnum {
// CHECK: @bar() unnamed_addr #0
loop {}
}

// CHECK: attributes #0 = {{{.*}} noreturn {{.*}}}

// CHECK: DISubprogram(name: "foo", {{.*}} DIFlagNoReturn
// CHECK: DISubprogram(name: "bar", {{.*}} DIFlagNoReturn

0 comments on commit 69ec4aa

Please sign in to comment.