diff options
| author | Josh Stone <jistone@redhat.com> | 2019-04-03 15:44:49 -0700 |
|---|---|---|
| committer | Josh Stone <jistone@redhat.com> | 2019-04-03 15:44:49 -0700 |
| commit | c2e0d7f1eb25bd9b4a8eaa7990cd0fd3a8c416bb (patch) | |
| tree | f9e3adc79aa84e1dc9059233e789da70ea05ff05 /src/librustc_codegen_ssa | |
| parent | e008e4fde837313d4a72da603ef492a721afc998 (diff) | |
| download | rust-c2e0d7f1eb25bd9b4a8eaa7990cd0fd3a8c416bb.tar.gz rust-c2e0d7f1eb25bd9b4a8eaa7990cd0fd3a8c416bb.zip | |
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.
Diffstat (limited to 'src/librustc_codegen_ssa')
| -rw-r--r-- | src/librustc_codegen_ssa/mir/block.rs | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 53e8f7ed88b..aaa0be20412 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -238,6 +238,13 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } + if self.fn_ty.ret.layout.abi.is_uninhabited() { + // Functions with uninhabited return values are marked `noreturn`, + // so we should make sure that we never actually do. + bx.abort(); + bx.unreachable(); + return; + } let llval = match self.fn_ty.ret.mode { PassMode::Ignore(IgnoreMode::Zst) | PassMode::Indirect(..) => { bx.ret_void(); |
