diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 193db15303f..30676b91620 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -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; } diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index bbe4e18b18c..97721ffbf06 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -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}; @@ -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); } diff --git a/src/test/codegen/noreturnflag.rs b/src/test/codegen/noreturnflag.rs index 24a5a4e44cb..7239223ca20 100644 --- a/src/test/codegen/noreturnflag.rs +++ b/src/test/codegen/noreturnflag.rs @@ -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 +#![crate_type = "lib"] -// CHECK: {{.*}}DISubprogram{{.*}}name: "foo"{{.*}}DIFlagNoReturn - -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