Rollup merge of #59639 - cuviper:ignore-uninhabited, r=eddyb
Never return uninhabited values at all
Functions with uninhabited return values are already marked `noreturn`,
but we were still generating return instructions for this. When running
with `-C passes=lint`, LLVM prints:
Unusual: Return statement in function with noreturn attribute
The LLVM manual makes a stronger statement about `noreturn` though:
> This produces undefined behavior at runtime if the function ever does
dynamically return.
We now emit an `abort` anywhere that would have tried to return an
uninhabited value.
Fixes #48227
cc #7463 #48229
r? @eddyb
This commit is contained in:
commit
05c31baf83
2 changed files with 39 additions and 0 deletions
32
src/test/codegen/noreturn-uninhabited.rs
Normal file
32
src/test/codegen/noreturn-uninhabited.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// compile-flags: -g -C no-prepopulate-passes
|
||||
// ignore-tidy-linelength
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum EmptyEnum {}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn empty(x: &EmptyEnum) -> EmptyEnum {
|
||||
// CHECK: @empty({{.*}}) unnamed_addr #0
|
||||
// CHECK-NOT: ret void
|
||||
// CHECK: call void @llvm.trap()
|
||||
// CHECK: unreachable
|
||||
*x
|
||||
}
|
||||
|
||||
pub struct Foo(String, EmptyEnum);
|
||||
|
||||
#[no_mangle]
|
||||
pub fn foo(x: String, y: &EmptyEnum) -> Foo {
|
||||
// CHECK: @foo({{.*}}) unnamed_addr #0
|
||||
// CHECK-NOT: ret %Foo
|
||||
// CHECK: call void @llvm.trap()
|
||||
// CHECK: unreachable
|
||||
Foo(x, *y)
|
||||
}
|
||||
|
||||
// CHECK: attributes #0 = {{{.*}} noreturn {{.*}}}
|
||||
|
||||
// CHECK: DISubprogram(name: "empty", {{.*}} DIFlagNoReturn
|
||||
// CHECK: DISubprogram(name: "foo", {{.*}} DIFlagNoReturn
|
||||
Loading…
Add table
Add a link
Reference in a new issue