1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//! `__builtin_unreachable`, which is the program promising control does not get here.
//!
//! Design: `spec/13-gnu-compat.md` section 13.5.
//!
//! The call has no value and no arguments, and what it means is a fact about the path it stands on
//! rather than anything to compute. So it becomes [`ExprKind::Unreachable`], a node with nothing
//! under it, and the lowering writes `unreachable_hint` where it stood. Nothing reads that yet: a
//! promise pays when a pass believes it and deletes the code after it, and there is no such pass.
//! Which is why honouring this costs nothing and refusing it cost a great deal.
//!
//! # Why the block does not end here
//!
//! gcc treats the call as the end of a path and everything after it as dead. That is an
//! optimization and not the meaning, and doing it in the front end would be doing it in the one
//! place that cannot check whether it was right. The promise is undefined behaviour when it turns
//! out false, so a compiler may do anything at all with the code below, and continuing to translate
//! it is one of the things it may do. It is also the one that keeps a program built at `-O0`
//! behaving the way its author watched it behave.
//!
//! What that gives up is the one thing the builtin is usually written for: a `switch` covering
//! every value of an enumeration, where the default arm is `__builtin_unreachable()` and the
//! function has no return after it. Here that function still runs off the bottom, which the walk
//! already ends with the `unreachable` terminator, so the two arrive at the same instruction from
//! opposite directions and the program is right either way.
//!
//! # Why this is answered after the call is checked
//!
//! The same reason `check/builtin/expect.rs` is. The row carries `void(void)`, so the call has a
//! prototype, and it is the prototype that reports `__builtin_unreachable(1)` in the ordinary
//! words. Recognising the name before the callee is looked up would mean writing that message
//! again here.
use Symbol;
use Span;
use crateChecker;
use crate;
/// The name, which is the whole of what this recognises.
const NAME: &str = "__builtin_unreachable";