pub enum Promise {
Off,
Blocks,
}Expand description
Whether the restrict contract is checked, from -fsafety-restrict.
Design: spec/safe-memory/09-type-init-and-races.md section 9.6, which is row Y8 of document
03 and is judgement J8. C 6.7.3.1 says that if an object reachable through a restrict pointer
declared in a block is modified anywhere in that block, every access to that object in that
block goes through that pointer. Nothing about one access decides it, which is why document 04
section 4.6 keeps it out of J1.
A flag rather than a default for two reasons, and neither of them is the one
Subobject has. The first is cost, and it is a bad distribution rather than a large number:
an access inside a block that declares restrict pointers pays a scan of that block’s record,
and blocks that declare them are the numeric kernels and the mem functions, which is exactly
where the hot loops are. Code with no restrict in it pays nothing at all. The second is that
the record is the union of what each pointer reached, so two pointers striding through one array
without ever landing on the same byte are reported, and by the letter of the standard those are
different objects and that is not a violation.
The second one is not an imprecision to apologise for. This check exists because a violated
restrict is a miscompilation, and what the optimizer acts on is that the ranges are disjoint,
so a program the union rule reports is a program the optimizer is entitled to break. It is
still a report about a program the standard permits, which is a decision that belongs to the
build rather than to this compiler.
Variants§
Off
No -fsafety-restrict. An access says which restrict pointer it went through, because
the alias analysis reads that, and nothing asks whether two of them met.
Blocks
-fsafety-restrict. Every block that declares restrict pointers keeps a record of what
each of them reached, and every access through one asks whether another got there first.