Bounds Checking
January 4, 2020 ยท View on GitHub
For a slice or array x, an expression like x[i .. j] is invalid unless the
compiler can prove that ((0 <= i) and (i <= j) and (j <= x.length())). For
example, the expression x[..] is always valid because the implicit i and
j values are 0 and x.length(), and a slice or array cannot have negative
length.
Similarly, an expression like x[i] is invalid unless there is a compile-time
proof that i is in-bounds: that ((0 <= i) and (i < x.length())). Proofs can
involve natural bounds (e.g. if i has type base.u8 then (0 <= i) is
trivially true since a base.u8 is unsigned),
refinements (e.g. if i has type
base.u32[..= 100] then 100 is an inclusive upper bound for i),
facts (e.g. an explicit prior check if i < x.length())
and interval arithmetic (e.g. for an
expression like x[m + n], the upper bound for m + n is the sum of the upper
bounds of m and n).
For example, if a is an array[1024] base.u8, and expr is some expression
of type base.u32, then a[expr & 1023] is valid (in-bounds). The bitwise-and
means that the overall index expression is in the range [0 ..= 1023],
regardless of expr's range.
Overflow Checking
Arithmetic overflow checking uses the same mechanisms as bounds checking. For
example, if m and n both have type base.u8 (or a refinement thereof) then
the expression m + n also has type base.u8. Proving that m + n evaluates
to something inside the base.u8 range, [0 ..= 255], is equivalent to
proving that the expression h[m + n] is valid (in-bounds) for a hypothetical
h array of length 256.
nullptr Checking
Guarding against nullptr dereferences is another case of bounds checking.
Like other programming languages, nptr T and ptr T are types: nullable and
non-null pointers to some type T. In Wuffs, the latter is effectively a
refinement. Assuming that nullptr is equivalent to 0, ptr T is
conceptually just (nptr T)[1 ..= UINTPTR_MAX], although that's not actually
valid syntax. Similarly, if expr is a pointer-typed expression then checking
that expr is not nullptr is equivalent to checking that expr is in the
range [1 ..= UINTPTR_MAX].