% !Tex root = checkedc.tex

\chapter{Bounds for expressions and bounds declaration checking}
\label{chapter:checking-bounds}

The prior chapter described how to declare bounds for variables.
This chapter describes how to infer a bounds expression for
an expression, starting from the declared bounds for variables.
An inferred bounds expression
describes the range of memory that can be accessed (if any) using
the values produced by expression.  Inferred bounds expressions
are used in runtime bounds checks.   This chapter also describes how to
 check that declared bounds for variables are valid at initialization
 time and after assignments.

Bounds expressions for expressions are inferred using inference
rules.  The inference rules are defined by induction over expressions,
the same way that typechecking rules work.  Given an expression
and bounds expressions for its subexpressions, a bounds expression
is constructed.  The induction base cases are variables (for which
bounds expressions are declared by the programmer) and constants.
The inference may require the compiler to introduce temporaries to
hold the values of subexpressions.

Bounds declarations are invariants about program variables
that must be checked at compile time.  The key idea is {\em subsumption checking}.
At \arrayptr\ variable declarations and assignments,
the right-hand side expression must have a bounds expression that includes (subsumes)
the declared bounds  expression for the variable.  The memory that is accessible using
the right-hand side must include all the memory that is accessible via the variable.
In addition, after assignments to variables used in declared bounds, the
declared bounds must still be valid.

Subsumption checking is parameterized by {\it sets of equivalent non-modifying expressions}.
Two non-modifying expressions are equivalent if they
evaluate to the same value given the program state at the program point where
checking is being done.  Assignments create equivalent non-modifying
expressions. Equivalence can also be inferred by dataflow analysis.

To handle both assignments to pointer variables with bounds and assignments
to variables used in bounds, we generalize bounds declaration
checking to operate over {\em contexts}.  Contexts are maps from variables
to bounds expressions for the values stored in the variables.
For each {\em full expression} in a function, we start with a context based
on declared bounds.
A full expression \cite[Annex C]{ISO2011} is an expression not nested within another expression.
We analyze the full expression and produce a new
context that describes the bounds for variables after assignments
in the expression have been completed.  We then check that the bounds
expressions in the context subsume the declared bounds for variables.

The analysis of expressions is complicated by C's evaluation
rules for expressions.  C does not have a precise order of evaluation
for expressions.  The times at which assignments
must happen within expressions are only partially constrained.
C also allows control flow within
expressions via comma expressions, conditional expressions, and
logical boolean expressions (the \code{&&} and \code{\|\|} expressions).

To handle this, the analysis tracks sets of variables where assignments
to those variables may not have been completed yet.  We call these
variables {\em pending variables} and the sets of variables {\em
pending sets}.  When the order of evaluation of expressions
is indeterminate, variables are added to pending sets.
The analysis tracks the flow of information through expressions, relying on the
pending sets to prevent undefined uses of variables or conflicting
assignments to variables.  We disallow some complicated expressions
that combine conditional assignments and unordered assignments
to variables used in the same bounds declaration.

The descriptions of bounds inference and bounds checking are
presented in a cumulative fashion.  We start with the simplest
analysis, bounds inference for expressions.  We then extend that
with progressively more complicated analyses.
Section~\ref{section:inferring-expression-bounds}
describes how to determine the bounds for an expression of type \arrayptr.
It does not cover operations that access data structures, such as member
access and pointer dereference.
Those are covered in Chapters~\ref{chapter:structure-bounds} and
\ref{chapter:pointers-to-data-with-arrayptrs}.
Section~\ref{section:checking-simple-assignment} describes
how to check bounds declarations for a simple assignment
expression.
Section~\ref{section:checking-complex-expressions}
extends this to cover more complex cases where there is control-flow
or multiple assignments within an expression.

Section~\ref{section:checking-full-expressions} describes
subsumption checking on bounds expressions.   The subsumption checking
puts expressions into a standard form.  It then uses syntactic equality,
extended with simple identities about C expressions and taking into account expression
equivalence information.
Inference steps for relational reasoning about bounds expressions
are described in Chapter~\ref{chapter:simple-invariants}.

Section~\ref{section:checking-function-call-arguments}
describes validating function call arguments.

\section{Preparing a translation unit for checking}

To simplify the rules for checking, some syntactic transformations are done
on a translation unit before checking.  First, some syntactic cases are
replaced with semantically-equivalent cases.  This reduces the number of cases
that must be covered by the checking rules.  In-line return bounds expressions
are replaced with the form that uses a name for the return value. The form
\boundsdecl{\var{f}(\ldots{})}{\var{e1}} is changed to
\texttt{\var{f}(\ldots{}) \keyword{where}
  \boundsdecl{\code{return_value}}{e1}}.
The \code{count} and
\code{byte_count} bounds expressions are also expanded to bounds expressions.
The form \boundsdecl{\var{x}}{\boundscount{\var{e1}}}
is replaced with \boundsdecl{\var{x}}{\bounds{\var{x}}{\var{x} \code{+} \var{e1}}}
and \boundsdecl{\var{x}}{\boundsbytecount{\var{e1}}}
is replaced with \boundsdecl{\var{x}}{\bounds{\cast{\arrayptrchar}{\var{x}}}
                                             {\cast{\arrayptrchar}{\var{x} \lstinline|+| \var{e1}}}}.
For now, we ignore the additional side conditions on count expressions. Checking of these
conditions will be addressed in Chapter~\ref{chapter:simple-invariants}.

Also, relative alignment is made explicit for all bounds
declarations: \boundsdecl{\var{x}}{\bounds{\var{e2}}{\var{e3}}} is expanded to
\boundsdecl{\var{x}}{\boundsrelval{\var{e2}}{\var{e3}}
                                  {\sizeof{\lstinline|typeof(|\var{x}\lstinline|)|}}}.
For code without explicit or implicit casts of \arrayptr s, relative
alignment can be ignored.

In the checking rules, sometimes shorter syntactic forms are used for
brevity. The shorter forms should be replaced with their full forms before
using the rules.

Second, lexical hiding of variables is eliminated by renaming variables so that
hiding no longer happens\footnote{Note that compilers typically do not need to
rename variables. Compilers already disambiguate variables with the
same name and the disambiguation mechanisms can be used in the implementation
of the checking rules.  For example, some compilers use distinct objects
to represent each variable declaration.}.  If a variable with block scope that does not
have external linkage has the same name as a variable with file scope or
a variable with an enclosing block scope, the variable
should be renamed to be distinct from other variables.  Similarly, parameter
variables that have the same name as a variable with file scope or a
variable with an enclosing block scope should be renamed.

\section{Inferring bounds expressions for expressions}
\label{section:inferring-expression-bounds}

We first discuss inferring bounds expressions for expressions. The bounds for an
expression are always determined with respect to a bounds
declaration context, which maps variables to their
bounds expressions.  We will use $\vdash$ to denote the
valid bounds for an expression. The notation \boundsinfer{\var{e}}{\var{bounds-exp}}
means that expression \var{e} has valid bounds \var{bounds-exp}.

At times, we need to discuss bounds that are given in terms of the value
of an expression or a subexpression.   For example, a function call expression may
return an \arrayptr\ pointer to an array of constant size
\var{n}. The bounds for that pointer value would be (the
\arrayptr\ pointer, the \arrayptr\ pointer +
\var{n}). We use temporaries to denote the values
of expressions or subexpressions.   A temporary is a compiler-introduced
temporary variable that is initialized immediately upon evaluation of an
expression.   It differs from a source-level variable, whose assignment
may happen at some less-precisely specified time.   The evaluation of
expressions at runtime needs to store values in a temporary,
if the temporary is used in a runtime
bounds check.

\subsection{Null pointers}

The bounds for 0 is the \lstinline|any| bounds:

\boundsinfer{0}{\boundsany}

\subsection{Variables}
\label{section:checking-variables}

Suppose there is a use of some variable \var{x}.

\begin{itemize}
\item
  If \var{x} has type \arrayptr, the bounds are the result of
  the analysis in Section~\ref{section:extent-definition}
  for this occurrence of \var{x}.
\item
  If \var{x} has type \ptrT,
  \boundsinfer{\var{x}}{\boundsrel{\var{x}}{\var{x} \code{+ 1}}{\var{T}}}.
   On the right-hand side, \var{x} is reinterpreted as having \arrayptr\ type.
\item
  If \var{x} has an array type, the rules depend on whether \var{x}  is a parameter
  variable.  Typechecking in C treats a parameter variable with the type ``array of \var{T}''
   as though it has the type ``pointer to \var{T}''.   It does not enforce
  at function calls that actual arguments have the required dimension size.  This means
  that the declared outermost bounds cannot be trusted for parameters with unchecked
  array types.  In contrast, local variables and externally-scoped variables are allocated
  space for their declared types.  Declared dimension information for them can be trusted
  regardless of whether they have checked or unchecked array types.  Checking of bounds
  declarations for checked arrays  enforces that actual arguments meet the required
  dimension size.
\begin{itemize}
\item If
\begin{itemize}
\item \var{x} is a local variable or an externally scoped variable
\item or \var{x} is a parameter variable with a checked array type
\end{itemize}
and \var{x} has a known number of elements \var{n}, then
  \boundsinfer{\var{x}}{\boundscount{\var{n}}}.
\item Otherwise, the bounds are the result of the analysis in
  Section~\ref{section:extent-definition} for this occurrence of \var{x}.
\end{itemize}
\item  Otherwise \var{x} has \boundsunknown.
\end{itemize}

\subsection{String literals and compound literal expressions}
A string literal \lstinline+''abc''+ evaluates to an lvalue with array type,
as does a compound literal of the form \lstinline+(int []) { 0, 1, 2, 3}+.
These lvalues are then converted implicitly to values with pointer type.

During bounds checking, a temporary is introduced for the result
of evaluating a string literal or compound literal expression.
If a literal \var{e} has array type and \var{n} elements, the bounds
exclude the null terminator, if there is one.
\begin{itemize}
\item If $e$ is a string literal or a compound literal expression with
a null-terminated array type,
\boundsinfer{\var{e}}{\bounds{temporary for \var{e}}{temporary for \var{e} + (\var{n - 1})}}.
\item Otherwise,
\boundsinfer{\var{e}}{\bounds{temporary for \var{e}}{temporary for \var{e} + \var{n}}}
\end{itemize}

\subsection{Address-of expressions}
\label{section:address-of-expression-bounds}

There are three kinds of address-of expressions:
\begin{itemize}
\item Address of a variable (\lstinline|&|\var{x}): a variable \var{x} with type \var{T}
whose address is taken is considered to be an array of one element:

\boundsinfer{\lstinline|&|\var{x}}
            {\boundsrel{\lstinline|&|\var{x}}{\lstinline|&|\var{x} \lstinline| + 1|}{\var{T}}}.

\item Address of a pointer dereference operation (\lstinline|&*|\var{e}):
The address-of operation and the pointer dereference operation cancel.
The bounds are the bounds of the underlying expression.
If \boundsinfer{\var{e}}{\var{bounds-exp}}, then
\boundsinfer{\lstinline|&*|\var{e}}{\var{bounds-exp}}.

\item Address-of a subscripting expression (\lstinline|&|\var{e1}\lstinline|[|\var{e2}\lstinline|]|):
This is the same as taking the address of a pointer dereference operation.
According to the C semantics, \var{e1}\lstinline|[|\var{e2}\lstinline|]| is equivalent
to \lstinline|*(|\var{e1} \lstinline|+| \var{e2}\lstinline|)|.  If
\boundsinfer{\var{e1} \lstinline|+| \var{e2}}{\var{bounds-exp}}, then
\boundsinfer{\lstinline|&|\var{e1}\lstinline|[|\var{e2}\lstinline|]|}{\var{bounds-exp}}.
\end{itemize}

\subsection{Function calls}
\label{section:inferring-bounds-for-function-calls}

Let \var{f} be the name of a function that returns an
\arrayptr\ value (pointers to functions will be handled later).
Suppose there is a function call expression of the form
\var{f}\code{(}\var{e1 \ldots{} en}\code{)}:

\begin{enumerate}
\item
  If \var{f} has a bounds declaration for the return value of the form
  \code{return_value :} \var{exp1}, then

  \begin{itemize}
  \item
    Any arguments that correspond to formal parameters occurring in
    \var{exp1} must be valid non-modifying expressions. If they are
    not, \boundsinfer{\var{f}\lstinline|(|\var{e1} \ldots{} \var{en}\lstinline|)|}{\boundsunknown}.
  \item
    Otherwise, substitute \var{e1} \ldots{} \var{en} for the formal
    parameters of \var{f} occurring in \var{exp1}. Also substitute the
    special symbol \exprcurrentvalue\ for
    \code{return_value}. These substitutions produce \var{exp2}.
    \boundsinfer{\var{f}\lstinline|(|\var{e1} \ldots{} \var{en}\lstinline|)|}{\var{exp2}}.
  \end{itemize}
\item
  If \var{f} does not have a bounds declaration for its return value,
  then \boundsinfer{\var{f}\lstinline|(|\var{e1} \ldots{} \var{en}\lstinline|)|}{\boundsunknown}.
\end{enumerate}

The special variable \lstinline|return_value| may appear in \var{exp1}. It
is the value of the function call expression. If \lstinline|return_value|
is used, a temporary variable is introduced to hold the result of the
function call.  The occurrences of \lstinline|return_value| are replaced
with the the temporary variable.

There needs to be validation that the bounds for argument expressions
match the required bounds for formal parameters. This is described in
Section~\ref{section:checking-function-call-arguments}.

The following code provides examples of function call expressions where
bounds need to be computed. In the code, the programmer wraps a call to
\code{malloc} in an allocation helper, \code{alloc_helper}. The
function \code{alloc_helper} returns an \arrayptr\ value
that is passed as an argument to \code{init}, which initializes the array
and returns the \arrayptr\ value.
\begin{lstlisting}
array_ptr<int> alloc_helper(int n) : count(n)
{
    array_ptr<int> result : count(n) = malloc((sizeof(int) * n);
    return result;
}

array_ptr<int> init(array_ptr<int> target : count(s),
                    int s) : count(s)
{
    for (int i = 0; i < count; i++) {
         target[i] = i;
    }

    return target;
}

void go(int size)
{
    array_ptr<int> x : count(size) = init(alloc_helper(size), size);
    ...
}
\end{lstlisting}

First, syntactic forms for bounds expressions are expanded to eliminate
count expressions and in-line return expressions, as well as make
relative alignment explicit.

\begin{lstlisting}
array_ptr<int> alloc_helper(int n)
where return_value : bounds(return_value, return_value + n) rel_align(int)
{
    array_ptr<int> result : bounds(result, result + n) rel_align(int) =
      malloc((sizeof(int) * n);
    return result;
}

array_ptr<int> init(array_ptr<int> target : bounds(target, target + s)
                                            rel_align(int),
                    int s)
where return_value : bounds(return_value, return_value + s) rel_align(int)
{
    for (int i = 0; i < count; i++) {
      target[i] = i;
    }

    return target;
}

void go(int size)
{
    array_ptr<int> x : bounds(x, x + size) rel_align(int) =
        init(alloc_helper(size), size);
    ...
}
\end{lstlisting}

The valid bounds for the call to \lstinline|init(alloc_helper(size),size)| in
\lstinline|go| are computed using the return bounds for \lstinline|init|:

\begin{lstlisting}
    return_value : bounds(return_value, return_value + s) rel_align(int)
\end{lstlisting}

First, there is a check that all the actual arguments corresponding to
the formal parameters used by the return bounds expression are valid
non-modifying bounds expressions. This check succeeds even though the
first actual argument \lstinline|alloc_helper(size)| is not a valid bounds
expression. The formal parameter \lstinline|target| is not used by the
return bounds expression.

Next, the actual arguments are substituted for the formal parameters and
a new temporary \var{t1} is substituted for \lstinline|return_value|.
(\var{t1} is distinct from source-level variables).
The argument \lstinline|size| is substituted for \lstinline|s|, producing
\begin{lstlisting}[escapechar=\|]
    init(alloc_helper(size), size) |\(\vdash\)| bounds(|\var{t1}|, |\var{t1}| + size) rel_align(int)
\end{lstlisting}

% TODO: we can now introduce a temporary for the result of the function call, so this
% is confusing given the discussion below for alloc_helper, where we do that.
%   Checking of call arguments would fail due to the potential inequality
% of two function call expressions.  These issues should be explained in checking of function arguments.
%
%It would not be possible to represent the bounds if \lstinline|size| were a
%function call too:
%\begin{lstlisting}
%    array_ptr<int> x = init(alloc_helper(getsize()), getsize());
%\end{lstlisting}
%
%Function calls are not valid in bounds expressions:
%
%\begin{lstlisting}[escapechar=\|]
%   bounds(|\var{t1}|, |\var{t1}| + getsize())  // illegal
%\end{lstlisting}
%
%The solution would be to assign the result of \lstinline|getsize()| to a
%variable:
%\begin{lstlisting}
%   int tmp = getsize();
%   array_ptr<int> x = init(alloc_helper(tmp), tmp);
%\end{lstlisting}

The parameters to the call to \lstinline|init| need to be validated
(see Section~\ref{section:checking-function-call-arguments}). This
requires determining the valid bounds for \lstinline|alloc_helper(size)|. The
return bounds for \lstinline|alloc_helper| are used:
\begin{lstlisting}
   return_value : bounds(return_value, return_value + n) rel_align(int)
\end{lstlisting}

First, there is a check that the actual arguments that correspond to
formal parameters used in the return bounds are valid non-modifying
expressions. The only argument is the variable size, so this check
succeeds. Next, \lstinline|size| is substituted for \lstinline|n| and
a new temporary variable \var{t2} is substituted for \lstinline|return_value|, producing:
\begin{lstlisting}[escapechar=\|]
   alloc_helper(size) |\(\vdash\)| bounds(|\var{t2}|, |\var{t2}| + size) rel_align(int)
\end{lstlisting}

\subsection{Pointer arithmetic}

The range of memory accessible through pointer arithmetic expressions
remains unchanged from the underlying pointer. In other words, for
\boundsinfer{\var{x}}{\var{bounds-exp}}, the bounds expression for any
pointer arithmetic involving \var{x} is the same as the one for
\var{x}. This is because that C semantics for pointer arithmetic is
that if \var{x} points to an object at runtime, any pointer arithmetic
involving \var{x} must produce a pointer to the same object. The bounds
of the object in memory are not changed by the pointer arithmetic.

We first cover the typical situation where the relative alignment type
for a pointer in a pointer operation matches the referent type of the
pointer. Given a pointer operation of the form \var{x op e1}, where \var{x}
has an \arrayptr\ type, \var{e1} has an integral type, and
\var{op} is addition or subtraction, the memory that can be accessed
through \var{x op e1} is the same memory that can be accessed through
\var{x}:

\begin{itemize}
\item
  If \var{x} is a pointer to \var{T} and
  \boundsinfer{\var{x}}{\boundsrel{\var{e2}}{\var{e3}}{\var{T}}},
  then \boundsinfer{\var{x} \var{op} \var{e1}}{\boundsrel{\var{e2}}{\var{e3}}{\var{T}}}.
\end{itemize}

This can be extended to pointer operations of the form \var{e4 op e1},
where \var{e4} has type
\arrayptrT\ as
follows:

\begin{itemize}
\item
  If \var{e4} is a pointer to \var{T} and
  \boundsinfer{\var{e4}}{\boundsrel{\var{e2}}{\var{e3}}{\var{T}}}
  then \boundsinfer{\var{e4 op e1}}{\boundsrel{\var{e2}}{\var{e3}}{\var{T}}}
\end{itemize}

Here is the full rule that handles the situation where the relative
alignment of the pointer differs from the size of the referent type of
the pointer. GCD computes the greatest common divisor of two integers.
The prior rules are just special cases of this rule:

\begin{quote}
If \var{e4} is a pointer to \var{T} and
\boundsinfer{\var{e4}}
            {\boundsrel{\var{e2}}
                       {\var{e3}}
                       {\var{c}}}
then \boundsinfer{\var{e4 op e1}}
                 {\boundsrel{\var{e2}}
                            {\var{e3}}
                            {\texttt{GCD(\var{c}, \sizeof{\var{T}})}}}.
\end{quote}

\subsubsection{Pointer arithmetic for unchecked pointer types}

Pointer arithmetic involving an \arrayptr\ value checks that
the value is non-null and generates a runtime error if it is. This check
is important because a null pointer may have invalid bounds (this
follows from the definition of the meaning of bounds in
Section~\ref{section:bounds-declarations}). It
prevents a null pointer that has invalid bounds from being used to create a
non-null pointer with valid bounds, which could then be used to access
memory.

Because the meaning of unchecked pointers has not changed, pointer
arithmetic involving a null unchecked pointer may not generate a runtime
error. The rules for array\_ptr pointer arithmetic can be applied to
unchecked pointer arithmetic, however, provided that a side condition that
the pointer expression is non-null is added:

\begin{quote}
If \var{e4} is a pointer to \var{T} and it can be proved that
\var{e4} \code{!= 0} and
\boundsinfer{\var{e4}}{\boundsrel{\var{e2}}{\var{e3}}}{\var{c}}, then
\boundsinfer{\var{e4 op e1}}{\boundsrel{\var{e2}}{\var{e3}}
                                            {\texttt{GCD(\var{c},\sizeof{\var{T}})}}}.
\end{quote}

Chapter~\ref{chapter:simple-invariants}
provides a general framework for checking side-conditions as
part of checking bounds declarations.

\subsection{Cast expressions}
\label{section:cast-expressions}

Given a cast expression of the form \cast{\var{T}}{\var{e}},
the bounds for \var{e} are determined. The bounds for
\var{e} are used as the bounds for the entire expression.

\subsection{Conditional expressions}

Given an expression of the form \var{e1} \code{?} \var{e2}
\code{:} \var{e3}, the bounds for \var{e2} and \var{e3} are
determined. They must be syntactically identical (after putting the
bounds into a normal form). The bounds for \var{e2} are used as the
bounds for the entire expression.

\emph{This is an expression where a conditional bounds expression could
be used to represent the resulting range.  Another alternative that works
with current syntax would be to create upper/lower-bound expressions
that use e1 such as (e1 ? lower-bound(e2) : lower-bound(e3), e1 ?
upper-bound(e2) : upper-bound(e3). For now, we defer discussion of both
alternatives. }

\subsection{Comma expressions}

Given an expression of the form \var{e1} \code{,} \var{e2}, the
bounds for \var{e2} are determined. The bounds for \var{e2} are used
as the bounds for the entire expression.

\subsection{Assignment expressions}

Given an expression of the form \var{e1} \code{ = } \var{e2}, the
bounds for \var{e2} are determined. The bounds for \var{e2} are used
as the bounds for the entire expression.

Note that if \var{e1} is a variable,
there is an order of evaluation issue if \var{e1} appears in the bounds for
\var{e2}.   Specifically, the bounds for \var{e2} cannot be used to
check a memory access within the full expression being evaluated.

\subsection{Pre-and-post increment operators}
\label{section:inferring-increment-bounds}

Given an expression of the form \code{++}\var{e1}, \code{--}\var{e1},
 \var{e1}\code{++} or \var{e1}\code{--}, where $e1$ has a pointer type,
 the bounds for $e1$ are the bounds for the entire expression.

 If $e1$ appears in its own bounds, the compiler should introduce a
 temporary to hold the value of $e1$ before the update, and use
 the temporary in the bounds.  In the case of post-increment operators,
 the C semantics already require  introducing a temporary for the value of $e1$.

\section{Bounds declaration checking for simple assignments}
\label{section:checking-simple-assignment}

This section describes how to check bounds declarations for
simple assignments to variables.  These are expression statements of the
form \code{v = e1}, where \code{v} is a variable and \code{e1} does
not contain nested assignments.
Section~\ref{section:checking-complex-expressions} handles nested assigments.

Given an expression of the form \var{v}\lstinline+=+\var{e}, the effect of the assignment
to \var{v} is modelled by updating the context to contain bound expressions that are true
after the assignment.  If \var{v} has \arrayptr\ type, the bounds expression in
the context for \var{v} is updated to the inferred bounds expression for \var{e}.
We also model the change in \var{v}'s
value for any bounds expressions in the context that use \var{v}.   If the result of
evaluating \var{e} is available in a temporary, we update the sets of equivalent
expressions to record that \var{v} equals the temporary when the (top-level) assignment
expression is completely evaluated.
We use the updated context and sets of equivalent expressions to check
that the new bounds expressions subsume the declared bounds expressions for variables.

For an assignment expression of the form \var{x} \code{=} \var{e},
where \var{x} is a variable and \var{e} is an expression, there are
three aspects to to computing bounds.
\begin{itemize}
\item Infer the bounds expression for \var{e}.
\item Determine the effect of the assignment on the
bounds declaration context.
We start with the context that is true before the expression
is evaluated and determine the context that is true after
the expression is evaluated.
\item If the value of \var{e} is also available in a temporary,
we record in the expression equivalence set that \var{x} equals that
temporary (at the end of evaluating the expression).
\end{itemize}
It seems straightforward to determine the effect of the assignment
on the context.   If \var{x} has type
\arrayptr, use the computed bounds for \var{e} to update the context
so that the bounds for \var{x} are the bounds of \var{e}.
However, there is a problem. The bounds for \var{e} is determined
\var{before} \var{x} changes value. When \var{x} changes value, the bounds
for \var{e} may no longer be true if \var{x} appears in the bounds.
The context could contain uses of \var{x} also in bounds expressions.

A simple solution is to invalidate bounds expressions where \var{x} appears in
the bounds. This does not work well when a variable that appears in its
own bounds declaration is incremented or decremented. Consider the
following example:
\begin{lstlisting}
array_ptr<int> x : bounds(x, high) = ...
int sum = 0;
while (x < high) {
    sum += *x;
    x++;  // bounds for x would be undefined for the simple solution
}
\end{lstlisting}

A possible solution is to require programmers to copy variables in loops
that are modified using only pointer arithmetic to temporary variables
before the loop. The temporary variables could then be used in bounds.
However, this might increase register pressure and worsen performance.

One can do better than that for loop induction variables, which are
variables that are incremented or decremented by a constant in a loop.
Condit \textit{et al.} observe that some assignment expressions are
invertible: the old value of a variable can be calculated from the new
value . One can update the bounds by substituting the inverted
expression in place of the variable. The updated bounds can then be
narrowed to satisfy loop bounds invariants. Invertible expressions
include the addition and subtraction expressions that update loop
induction variables.

The updated context is determined in two steps. First, if
\var{x} has type \arrayptr, the context is updated for
\var{x} using bounds expressions that use the \emph{old} value of \var{x}:

\begin{enumerate}
\item
  If \boundsinfer{\var{e}}{\var{exp}}, then the context is updated with
  \boundsdecl{\var{x}}{\var{exp}}.
\item
  Otherwise, the context is updated with \boundsdecl{\var{x}}{\boundsunknown}
   to indicate that \var{x} has no valid bounds.
\end{enumerate}

Second, the context is updated to reflect the change in the value of
\var{x}:

\begin{itemize}
\item
  If the expression being assigned is invertible, the right-hand side of
  any bounds expression that uses \var{x} will be updated to use an
  expression that inverts the new value to compute the old value.
\item
  Otherwise, any bounds expression that involves \var{x} is invalidated
\end{itemize}

\subsection{Invertibility}

The following examples illustrate invertibility and updating bounds. For
the first example, suppose there is a declaration of an
\arrayptr\ variable followed by a decrement of a variable
involved in the bounds:

\begin{lstlisting}
array_ptr<int> a : count(len) = ...
len = len - 1
\end{lstlisting}

The original value of \lstinline|len| can be computed from the new value.
In this case, a valid new bounds after the decrement of \lstinline|len| is
\lstinline|count(a)  == len + 1.| The bounds for \lstinline|a| after the
assignment are:
\begin{lstlisting}
len = len - 1
where a : count(len + 1);
\end{lstlisting}

For the second example, consider an update to a pointer variable that
appears in its own bounds:
\begin{lstlisting}
array_ptr<int> p : bounds(p, high) = ...
while (p < high) {
    ...
          p = p + 1;
}
\end{lstlisting}

First, the new bounds expression for the expression \lstinline|p + 1| is
computed. It is the same as the original bounds expression
\lstinline|bounds(p, high)|. Because \code{p} is modified by the assignment, the
inverted expression for \lstinline|p + 1| is substituted into
\lstinline|(p, high)|. The inverted expression for \lstinline|p + 1| is \lstinline|p - 1|.
This leads to bounds of the form \lstinline|bounds(p - 1, high)|:

\begin{lstlisting}
while (p < high) {
    ...
          p = p + 1 where p : bounds(p - 1, high);
}
\end{lstlisting}

Bounds validity is preserved when the range of a bounds expression is
narrowed. \lstinline|(p - 1, high)| implies that \lstinline|(p, high)| is a
valid bounds expression. This reestablishes the loop bounds invariant
for \lstinline|p| of \lstinline|(p, high)|.

\begin{lstlisting}
while (p < high) {
    ...
          p = p + 1 where p : bounds(p, high);
}
\end{lstlisting}

The correctness of narrowing depends on pointer arithmetic overflow
for checked pointer types being a runtime error. For a lower bound \var{e1} in a bounds
expression, we can only substitute \var{e2} for \var{e1} as the lower
bound if \var{e2} \code{>=} \var{e1}. The identity \code{p > p - 1}
holds only if overflow is a runtime error.

\subsection{Invertible expressions}
An expression is invertible with respect to a variable \var{x} if:

\begin{enumerate}
\item
  The expression is \var{x}
\item
  or

  \begin{enumerate}
  \item
    The operator in the expression is an addition, subtraction, one's
    complement, unary minus, unary plus, exclusive-or, a bit-preserving
    cast operator, or a widening cast operator, and
  \item
    The variable \var{x} occurs only in one argument of the operation and that
    argument is an invertible expression with respect to \var{x}, and
  \item

    Any other argument of the operation is a non-modifying expression,
    excluding non-modifying expressions that are or include member
    references, indirect member references, or pointer dereferences.
  \end{enumerate}
\end{enumerate}

The addition and subtraction operations must be for checked pointer
arithmetic or unsigned integer arithmetic. An implementation may allow
integral addition and subtraction operations to be invertible if
integral addition and subtraction are defined as two's complement
arithmetic where extra bits are discarded on overflow. However, this
introduces the possibility of non-portable code.

Given the expression \var{x} \code{=} \var{e}, where \var{x} occurs once
in \var{e}, mathematical rules are applied to solve for \var{x} in
\var{e}. We generalize the left-hand side from \var{x} to an expression
\var{f} and define \texttt{inverse(}\var{f}\texttt{,}
\var{e}\texttt{)} as follows:

\begin{longtable}[c]{@{}ll@{}}
\toprule
Given \texttt{inverse(\var{f}, \var{e})}, where & the result is:\tabularnewline
\midrule
\endhead
\var{e} = \texttt{x} & \var{f}\tabularnewline
\var{e} = \code{\~}\var{e1} &
\texttt{inverse(\code{\~}\var{f}, \var{e1})}\tabularnewline
\var{e} = \code{-}\var{e1} & \texttt{inverse(\code{-}\var{f}, \var{e1})}\tabularnewline
\var{e} = \code{+}\var{e1} & \texttt{inverse(\code{+}\var{f}, \var{e1})}\tabularnewline
\var{e} = \cast{\var{t1}}{\var{e1}}, where \var{e1} has
type \var{t2} & \texttt{inverse(\cast{\var{t2}}{\var{f}},
\var{e1})}\tabularnewline
and \code{(}\var{t1}\code{)} is not a narrowing cast & \\
\var{e} = \var{e1} \code{+} \var{e2}, where \texttt{x} occurs in
\var{e1} & \texttt{inverse(}\var{f} \code{-} \var{e2},
e1)\tabularnewline
\var{e} = \var{e1} \code{+} \var{e2}, where \texttt{x} occurs in
\var{e2} & \texttt{inverse(}\var{f} \code{-} \var{e1},
\var{e2})\tabularnewline
\var{e} = \var{e1} \code{-} \var{e2}, where \texttt{x} occurs in
\var{e1} & \texttt{inverse(}\var{f} \code{+} \var{e2},
\var{e1})\tabularnewline
\var{e} = \var{e1} \code{-} \var{e2}, where \texttt{x} occurs in
\var{e2} & \texttt{inverse(}\var{e1} \code{-} \var{f},
\var{e2})\tabularnewline
&\tabularnewline
\var{e} = \var{e1} \code{^} \var{e2}, where \texttt{x} occurs in
\var{e1} & \texttt{inverse(}\var{f} \code{^} \var{e2},
\var{e1})\tabularnewline
\var{e} = \var{e1} \code{^} \var{e2}, where \texttt{x} occurs in
\var{e2} & \texttt{inverse(}\var{f} \code{^} \var{e1},
\var{e2})\tabularnewline
\bottomrule
\end{longtable}

Given \texttt{inverse(x}, \var{e}), the rules are applied repeatedly
until the original value of x in e has been computed. Here is an example
of computing the inverse of \code{x = (x + 4) + 5}:
\begin{lstlisting}
   inverse(x, (x + 4) + 5) =
       inverse(x - 5, x + 4) =
          inverse((x - 5) - 4, x) =
              (x - 5) - 4
\end{lstlisting}

\section{Bounds declaration checking for expressions}

\label{section:checking-complex-expressions}

This section generalizes bounds declaration checking for a single
assignment expression to expressions with control-flow or multiple
assignments.
It builds on the bottom-up analysis in
Section~\ref{section:inferring-expression-bounds}.

\subsection{Order of evaluation and checking}
\label{section:avoiding-undefinedness}

The order of evaluation of side-effects in subexpressions of an expression is defined in C only for
control-flow expressions and in certain other circumstances \cite[Section 6.5,Annex C]{ISO2011}).
Otherwise, the order of evaluation of side-effects is undefined.   This complicates checking
because an expression with an undefined order of evaluation of side-effects might have an
undefined meaning.  Checking must produce an error for these expressions because the
validity of bounds information is not maintained by such expressions. In addition, checking must still
model the order of side-effects when the order is defined.

The meaning of an expression is undefined if:

\begin{enumerate}
\item
  There are multiple assignments to the same variable within an
  expression where the order of evaluation of the assignments is
  undefined, or
\item
  There is an assignment to a variable that is also used by the
  expression, where the order of evaluation of the assignment and the
  use is undefined.
\end{enumerate}

The following statements illustrate these problems:

\begin{lstlisting}
y = (x = 5) + (x = 6);
i = i++ + 1;
a[i++] = i;
\end{lstlisting}

In the first case, the value of the right-hand side expression is 11,
yet at the end of the expression, the value of x could be 5 or 6. In the
second case, there are two assignments to i and the order is undefined.
In the third case, it is not clear when i is read versus when it is
modified.

Note that a C compiler may choose an order of evaluation and
define the meaning of an expression anyway.  We still
require that a compiler produce an error when checking
bounds declarations for expressions with undefined meaning
according to the definition just given.  This ensures that the checking
is the same across compilers.

Bounds checks can lead to a subtle version of an unordered assignment
and use.  An expression may have an assignment through a pointer that requires a
bounds check. The bounds for the pointer expression may include a
variable that is modified in the expression, where the order of
evaluation of the assignment through the pointer and the variable
assignment is undefined. This means that the order of evaluation of the
bounds check and the variable assignment is undefined.

This example illustrates this problem:

\begin{lstlisting}
w = ...
where w : bounds(x, x + y);
int t = *w + (y = tmp);
\end{lstlisting}

The variable y is an integer variable that is a count of elements. It is
overwritten during the evaluation of an expression that dereferences w,
whose bounds include y.

\subsection{Checking overview}
There are three aspects to the checking:
\begin{itemize}
\item Modelling the effect of assignments on the bounds
of variables by calculating an updated context.
\item Tracking and calculating sets of equivalent (non-modifying) expressions.
\item Detecting undefined behavior.
\end{itemize}
The updated context and equivalence information are used to prove that bounds
declarations remain valid.

To detect undefined behavior, the checking tracks the set of variables that
may be read (used) or written (assigned to) by an expression.   When checking an expression with
subexpressions that have an undefined order of evaluation with respect to each
other, there is a check that the variables read or assigned to by one subexpression
do not overlap with the variables assigned to by another subexpression.  This is undefined
behavior according to the C Standard.

When two expressions have no order of evaluation specifed, an assignment in one expression
may or may not completed the other expression (or its subexpressions) are evaluated.
This means that the variable being assigned to has an {\em indeterminate} value when the
other expression is evaluated. The checking detects to detect:
\begin{enumerate}
\item Uses of variables whose values are indeterminate.
\item Accessing memory with pointers whose bounds expressions
are indeterminate because they use a variable whose value is indeterminate.
\item Unsequenced assignments to the same variable.
\end{enumerate}

The C Standard
describes a sequence relation between pairs of expressions $(e1, e2)$:
the expression $e1$ must be evaluated before $e2$ \cite[Section 5.1.2.3]{ISO2011}.
The C Standard
further divides sequencing of expressions into value computations
of expressions and side effects of expressions \cite[Section 6.5, pars. 1,2]{ISO2011}.
Side effects of an expression may be completed at a different time than the value
computation of the expression.
Given an assignment of the form $e1 = e2$,
the value computations of $e1$ and $e2$ are sequenced before the
assignment. The checking takes into account both forms of sequencing.
For side-effects that must be completed before the evaluation of another
expression $e$, we do not check that those side-effect conflicts with $e$.

We introduce the following notation:
\begin{enumerate}
\item Given a context $C$, $C[v]$ returns the value for variable $v$ in $C$.
\item $C[v \mapsto B]$ produces a new context that is identical to $C$,
except that variable $v$ is mapped to $B$.
\item $v \in dom(C)$ means $v$ has an entry in $C$ ($v$ is in the domain of $C$).
\item $EQ - S$ takes sets of equivalent expressions $EQ$  and a set of variables
$S$.  It produces new sets by removing any expressions that use the value
of variables in $S$.
\end{enumerate}

The checking is done by the following functions:
\begin{enumerate}
\item $CheckOverlap$: given the read and write sets for two expressions, check if
the variables read or written by one expression are written by other expression.
\item $Update$: updates the context, the sets of equivalent expressions,
and other information to be valid for the program state after
a side-effect is completed.
\item $Check$ and $CheckLValue$:  these mutually recursive
functions check expressions.  For an expression, they compute
its bounds, an updated context, updated sets of equivalent expressions,
and a set of expressions that produce the same value as the expression.
$Check$ handles expressions that
produce values, while $CheckLValue$ handles expressions that produce
lvalues.  In C, when an lvalue expression is used where a value is
expected, the lvalue is converted implicitly to a value by
reading the memory for the lvalue.
\item $Validate$: checks that the updated context
and sets of equivalent expressions imply that the declared bounds for
variables are valid.
\item $CheckFullExpr$: checks that declared bounds are valid after
evaluating a full expression.
\end{enumerate}

\subsection{Checking expressions with unordered evaluation of operands}

When an assignment $a$ to a variable $v$ happens, the context and sets of equivalent expressions
need to be updated so that they are valid for the program state after the assignment is complete.
The function $Update(v, \mathit{OV}, B, C, \mathit{EQ}, G)$ takes:
\begin{itemize}
\item A variable $v$ that is being assigned to.
\item An optional expression $\mathit{OV}$
that evaluates in the updated program state to the value of $v$
before the assignment.   $\mathit{OV}$ stands for original value.
$\mathit{OV}$ is either an expression
or the special value {\it None}.
\item A bounds expression $B$ for the value being assigned to $v$.
\item A context $C$.
\item Sets of equivalent expressions $\mathit{EQ}$.
\item A set of equivalent expressions $G$ that produce the same value being assigned to $v$.
\end{itemize}
It returns updated bounds $\mathit{UB}$, context $\mathit{UC}$, and
sets of equivalent expression ($\mathit{UEQ}$, and $\mathit{UG}$)
that are valid in the program state after the assignment.

Its definition is:
\begin{enumerate}
\item Let $\mathit{UC} = C$.
\item If $v$ has \arrayptr\ type and declared bounds, let $\mathit{UC} = \mathit{UC}[v \mapsto B]$.
\item Update $\mathit{UC}$ to reflect the effect of the assignment on existing entries.
For any variable $x$ where $\mathit{UC}[x] = B_x$ and $B_x$ uses the value of $v$,
\begin{enumerate}
\item If $OV$ is {\it None}, let $\mathit{UC} = \mathit{UC}[x \mapsto$ \boundsunknown $]$.
\item  Otherwise, let $B_x^\prime = B_x$ with $OV$ substituted for the use of $v$.
Let $\mathit{UC} = \mathit{UC}[x \mapsto B_x^\prime]$
\end{enumerate}
\item Let $UB = B$.  If $UB$ uses $v$, update $UB$ the same way that entries in $UC$
are updated:
\begin{enumerate}
\item If $OV$ is {\it None}, let $UB = $ \boundsunknown.
\item Otherwise, substitute $OV$ for $v$ in $UB$.
\end{enumerate}
\item Record the new bounds for $v$: let $\mathit{UC} = \mathit{UC}[v \mapsto UB]$.
\item Let $UEQ = EQ$.  Adjust $UEQ$ so that it is true for the program state after the assignment: for any expression $d$ in $UEQ$ that uses the value of $v$,
\begin{enumerate}
\item If $OV$ is {\it None}, let $UEQ$ = $UEQ $ - $d$.
\item Otherwise, substitute $OV$ for the use of $v$ in $d$.
\end{enumerate}
\item Let $UG = G$. Update the set of equivalent expressions $G$ similarly to $UEQ$. Add $\{v\}$ to $UG$.
\item If $UG$ is not a singleton set, add $UG$ to $UEQ$.
\end{enumerate}

The functions $Check$ and $CheckLValue$ are the main bounds declaration
checking functions.  $Check$ handles expressions that produce values,
while $CheckLValue$ handles expressions that produce lvalues.  They do three
things: compute the bounds expression for an expression, maintain and compute
equality information, and check for undefined behavior due to the interaction
of side-effects with the undefined order of evaluation.  The equality information
tracks expressions that are equivalent (evaluate to the same value)
after the expression and its side-effects have been evaluated.
It also computes non-modifying expressions that will evaluate to the value
produced by the expression being checked.  $Check$ is parameterized so
that the same logic can  be re-used across assignments, compound assignments,
and pre/post-increment expressions.

The function $Check(e, C, EQ, Form, FB)$ takes as inputs:
\begin{enumerate}
\item An expression $e$ that evaluates to a value.
\item A context $C$.
\item Sets of equivalent expressions $EQ$.
\item Whether $e$ is special instruction form.  This can have 3 values: $No$, $PostIncDec$,
and $Compound$.
\item An optional bounds $FB$ for the first operand of $e$.
This is used when checking compound assignments and pre/post-increment expressions.  These are
expanded to the form $e1~=~e1~op~e2$ where $e1$ is only processed once.
\end{enumerate}

$Check$ returns:
\begin{enumerate}
\item A bounds expression $B$ for the values at runtime to which $e$ evaluates.
\item An updated context $\mathit{UC}$.
\item Updated sets of equivalent expressions $UEQ$.
\item A set of equivalent expressions $G$ that will produce the same value as $e$.
\item A set $R$ of variables that may be read during evaluation of $e$.
\item A set $W$ of variables that may be written during evaluation of $e$.
\item It may also report an error.
\end{enumerate}
The results produced by $Check$ are valid in the program state
{\em after} the assignments in $e$ have been completed.

The function $CheckLValue(e, C, EQ)$ is similar to $Check$.  It takes the
same first 3 arguments as $Check$, except that $e$ evaluates to an lvalue.
It returns:
\begin{enumerate}
\item A bounds expression $B$ for the lvalues produced by $e$.
\item A bounds expression $RB$ for values read from the lvalues produced by $e$.
\item An updated context $\mathit{UC}$.
\item Updated sets of equivalent expressions $UEQ$.
\item A set of equivalent expressions $G$ that produce the same lvalue as $e$.
\item A set $R$ of variables that may be read during evaluation of $e$.
\item A set $W$ of variables that may be written during evaluation of $e$.
\item It may also report an error.
\end{enumerate}

The function $CheckOverlap(R_1, W_1, R_2, W_2)$ takes the set of variables read and written
by expressions $e_1$ and $e_2$:
\begin{enumerate}
\item  $R_1$ and $W_1$ are the variables read and written by $e_1$, respectively.
\item  $R_2$ and $W_2$ are the variables read and written by $e_2$, respecitively.
\end{enumerate}
It reports an error if $(R_1 \cup W_1) \cap W_2$ is not empty, or
$(R_2 \cup W_2) \cap W_1$ is not empty.

The function $NeedsBoundsCheck(e)$ takes
an expression that evaluates to an lvalue and determines if an
assignment to $e$ requires a bounds check.

The definition of $Check(e, C, EQ, Form, FB)$ is:
\begin{enumerate}
\item If $e$ is an lvalue expression
\begin{enumerate}
\item Let $(B_{lv}, RB, \mathit{UC}, UEQ, G_{lv}, R_{lv}, W_{lv}) = CheckLValue(e, C, EQ)$.
\item If $e$ has array type, let $B = B_{lv}$, $G = G_{lv}$, $R = R_{lv}$, and $W = W_{lv}$.
\item If $e$ does not have array type, there will an implicit read of the lvalue produced by $e$
at runtime.
\begin{enumerate}
\item Let $R = R_{lv}$,  $W = W_{lv}$, and $B = RB$.
\item If $e$ is a (possibly-parenthesized) variable $v$, let $R = R \cup \{ v \}$.
\item Otherwise, if $NeedsBoundsCheck(e)$ returns true,
a compiler will insert a bounds check  to ensure $e$ is a valid memory location to access.
\begin{enumerate}
\item Let $Q$ be the variables that may be read by $B_{lv}$.
\item Check that $B_{lv}$ does not use any variables written by $e$ by calling $CheckOverlap(Q, W_{lv})$.
\item Let $R = R \cup Q$.
\end{enumerate}
\item If $e$ is an element of a set of equivalent expressions $F$ in $UEQ$ , let $G = F$ (note that
in this case, $e$ must be a non-modifying expression.  This implies that the sets of equivalent
expressions do not change during $CheckLValue(e, C, EQ)$ and $EQ = UEQ$).
\item Otherwise, if $e$ is non-modifying expression and $e$ does not read memory via a pointer, let $G = \{ e \}$.
\item Otherwise, let $G = \emptyset$ (we address aliasing of memory accesses in another section).
\end{enumerate}
\end{enumerate}

% lhs = rhs

\item If $e$ has the form $lhs = rhs$,
\label{list:check-assignment}
\begin{enumerate}
\item Let $(B_{lhs}, RB, \mathit{UC}_{lhs}, {UEQ}_{lhs}, \_, R_{lhs}, W_{lhs}) = CheckLValue(lhs, C, EQ)$.
\item Let $(B_{rhs},  \mathit{UC}_{rhs}, {UEQ}_{rhs}, G_{rhs}, R_{rhs}, W_{rhs}) =
Check(rhs, \mathit{UC}_{lhs}, {UEQ}_{lhs}, Form, RB)$.
\item $lhs$ and $rhs$ do not have a specified order of evaluation with respect to each other,
so call $CheckOverlap(R_{lhs}, W_{lhs}, R_{rhs}, W_{rhs})$.
\item Let $R = R_{lhs} \cup R_{rhs}$ and $W = W_{lhs} \cup W_{rhs}$.
\item If $NeedsBoundsCheck(lhs)$ returns true, let $Q$ be the variable that may be read by $B_{lhs}$.
Check that the bounds check does not use any variables written by either $lhs$ or $rhs$ by
calling $CheckOverlap(Q, W)$.   Let $R = R \cup Q$.
\item  If $lhs$ is a variable $v$ (that is, $GetLValueVariable(lhs) = { v }$),
\begin{enumerate}
\item Let $W = W \cup \{ v \}$.
\item Determine whether there is an expression that computes the old value of $v$:
\begin{enumerate}
\item If $rhs$ can be inverted with respect to $v$, let $iv = inverse(v, rhs)$.
\item Otherwise, if $UEQ$ contains a set of equivalent expressions $F$ that contains $v$ as
an element, and $F$ contains a variable $w \neq v$, set $iv$ to $w$ (Note that $w$ is a representative
from $F$.  If during later processing  an assignment to $w$ is seen, another variable from $F$ will be chosen).
\item Otherwise, let $iv = $ {\it None}.
\end{enumerate}
\item Let $(B, \mathit{UC}, UEQ, G) = Update(v, iv, B_{rhs}, \mathit{UC}_{rhs}, UEQ_{rhs}, G_{rhs})$.
\end{enumerate}
\item If $lhs$ is not a variable, let $(B, \mathit{UC}, UEQ, G) = (B_{rhs}, \mathit{UC}_{rhs}, UEQ_{rhs}, G_{rhs})$
(we address aliasing of memory accesses in another section).
\end{enumerate}

% lhs op= rhs

\item If $e$ has the form $lhs~op= rhs$, the result is
$Check (lhs = lhs~op~rhs, C, EQ, Compound, None)$.

\item For pre- and post-increment/decrement forms, if $e$ has the form:
\begin{enumerate}
\item \code{++}$e1$, the result is  $Check(e1$ \code{ = } $e1$ \code{ + 1}$,C, EQ,
Compound, None)$.
\item \code{--}$e1$, the result is $Check(e1$ \code{ = } $e1$ \code { - 1}$, C, EQ,
Compound, None)$.
\item $e1$\code{++}, the result is  $Check(e1$ \code{ = } $ e1$ \code { + 1}$,
C, EQ, PostIncDec, None)$.
\item $e1$\code{--}, the result is $Check(e1$ \code{ = } $ e1$ \code{ - 1}$, C, EQ, PostIncDec, None)$.
\end{enumerate}
\item If $e$ has the form \code{&}$e1$, let $(B, \_, \mathit{UC}, UEQ, G, R, W) = CheckLValue(e1, C, EQ)$.

\item Otherwise, $e$ is some expression with $n$ subexpressions (n may be 0).  The
result is
\label{list:check-unordered-operands}
\begin{enumerate}
\item Let $\mathit{UC} = C$ and $UEQ = EQ$.  Let $S_k$ designate the $k^{th}$ subexpression.
\item Visit the $n$ subexpressions  accumulating results into $\mathit{UC}$ and $UEQ$.  Choose an
order where the subexpression whose bounds are used to compute the bounds
of this expression is visited last.\footnote{We require this order so that bounds of the subexpression do
not have to be passed to calls to $Check$.  The bounds of the subexpression already reflect the effect of
assignments to variables in other subexpressions.  With other orders, if the bounds used variables assigned
to by other subexpressions, the bounds would need to be updated by $Check$.}
If the current subexpression being visited is $S_i$,
\begin{enumerate}
\item If $i = 1$ and $Form = PostIncDec$ or $Form = Compound$, $S_1$ has already
been checked, so use the results from that.  Let $B_1 = FB, R_1 = \emptyset, W_1 = \emptyset$.
If $S_1$ appears in some set $F$ in $UEQ$,  let $G_1 = F$. Otherwise, let $G_1 = \emptyset$.
\item Otherwise, let $(B_i, \mathit{UC}, UEQ, G_i, R_i, W_i) =$  $Check(S_i, \mathit{UC}, UEQ, No, None)$.
\item For any subexpression $k$ whose bounds $B_k$ has already been computed,
\begin{enumerate}
\item Let $Q$ be the variables read by $B_k$.  If $Q \cap W_i$ is non-empty, let $B_i = $ \boundsunknown
(the $B_i$ does not reflect any changes to variables in $W_i$, so it is set conservatively to \boundsunknown).
\item  Also let $G_k = G_k - W_i$.
\end{enumerate}
\end{enumerate}
\item Check that no subexpression writes variables that are read or written by another subexpression.
For each pair of subexpressions $(i, k)$, $CheckOverlap(R_i, W_i, R_k, W_k)$.
\item Determine the set of equivalent expressions for $e$.  Recall that the equivalent expressions must be non-modifying expressions.
\begin{enumerate}
\item If $Form = PostIncDec$, let $Val = S_1$.  Otherwise, let $Val = e$.
\item If $Val$ is a non-modifying expression, let $G  = \{ Val \}$.
\item If $Val$ is a call expression, let $G = \emptyset$.
\item Otherwise, try to construct a version $Val^\prime$ of $Val$ that computes the same value
      as $Val$ but is a non-modifying expression.

      For any subexpression $S_i$ that is a modifying expression,
      use an expression from $G_i$ (or $G_1$ when $Form = PostIncDec$). If $G_i$ is empty, $Val^\prime$ cannot
      be constructed.
\item If $Val^\prime$ can be constructed, let $G = \{ Val^\prime \}$.  Otherwise, let $G = \emptyset$.
\end{enumerate}
\item Use the rules in Section~\ref{section:inferring-expression-bounds} to compute B using the $B_i$.
\item If computing $B$ introduces a temporary $t$ to hold the value produced by evaluating $e$, add $t$ to $G$.
\end{enumerate}
\end{enumerate}

The definition of $CheckLValue(e, C, EQ)$ is:
\begin{enumerate}
\item If $e$ is a variable $v$, let $\mathit{UC} = C$, $UEQ=EQ$, $R = \emptyset$, $W = \emptyset$,
\begin{enumerate}
\item If $v$ does not have array type,
\begin{enumerate}
\item Let $B = bounds(\&v,\&v + 1)$.
\item If $v \in dom(C)$, let $RB = C[v]$.  If $v \notin dom(C)$, let $RB =$ \boundsunknown.
\item Let $G=\{$ \code{&}$v \}$.
\end{enumerate}
\item Otherwise, $v$ has an array type.
\begin{enumerate}
\item If $v$ has a known number of elements $n$ and
\begin{enumerate}
\item If $v$ has a checked array type, or
\item $v$ has an unchecked array type and is a local variable or externally-scoped variable,
\end{enumerate}
Let $B = bounds(v, v + n)$ and $G =\{ v \}$.
\item Otherwise, let $B = $ \boundsunknown and $G = \emptyset$.
\item Let $RB = $ \boundsunknown (Checked C does not allow bounds for values stored in arrays).
\end{enumerate}
\end{enumerate}
\item If $e$ has the form $*e1$,  let $(B, \mathit{UC}, UEQ, \_, R, W) = Check(e1, C, EQ, No)$.  Let $G =\emptyset$ and $RB = $ \boundsunknown (Checked C does not allow bounds for values pointed to by pointers).
\item If $e$ has the form $e1[e2]$,
\label{list:check-unordered-subscript-operands}
\begin{enumerate}
\item Let $(B_{e1}, \mathit{UC}_{e1}, {UEQ}_{e1}, \_, R_{e1}, W_{e1}) = Check(e1, C, EQ,  No,
         None)$.
\item Let $(B_{e2}, \mathit{UC}_{e2}, {UEQ}_{e2}, \_, R_{e2}, W_{e2}) = Check(e2, \mathit{UC}_{e1}, {EQ}_{e1},
         No, None)$
\item The order of evaluation of $e1$ and $e2$ is unspecified, so
         call $CheckOverlap(R_{e1}, W_{e1}, R_{e2}, W_{e2})$.
\item Choose the $e_i$ that has pointer type.   Let $B = B_{e_i}$, $\mathit{UC} = \mathit{UC}_{e2}$,
$UEQ  = {UEQ}_2$,  $G=\emptyset$, $RB = $ \boundsunknown, $R = R_{e1} \cup R_{e2}$, and
$W = W_{e1} \cup W_{e2}$.
\end{enumerate}
\item If $e$ has the form $(e1)$, the result is $CheckLValue(e1, C, EQ)$
\end{enumerate}

The definition of $NeedsBoundsCheck(e)$ is:
\begin{enumerate}
\item If $e$ has the form $(e1)$, $NeedsBoundsCheck(e1).$
\item If $e$ has the form $*e1$ and $e1$ has an \arrayptr\ type, true.
\item If $e$ has the from $e1[e2]$ and the pointer-typed subexpression has \arrayptr\ type, true.
\item Otherwise, false.
\end{enumerate}

\subsection{Full expressions}

$CheckFullExpr(e)$ checks that declared bounds are valid after
evaluating a full expression.  It starts with a context based on the
declared bounds. It computes an updated context and equality information
implied by $e$.  It then checks that the updated context
and sets of equivalent expressions imply the declared bounds.

The routine $Validate(DC, \mathit{UC}, EQ)$ takes a full expression $e$, a context $C$,
constructed using declared bounds, an updated context $\mathit{UC}$, and sets of equivalent expressions $EQ$
that is valid when $\mathit{UC}$ is valid.  It checks that $\mathit{UC}$ and $EQ$ imply the validity of $DC$.

$CheckFullExpr(e)$ is defined as follows:
\begin{enumerate}
\item Let $DC$ be the context formed from declared bounds.
\item Let $(\_, \mathit{UC}, UEQ, \_, \_, \_) = Check(e, DC, \emptyset, No, None)$.
\item Call $Validate(DC, \mathit{UC}, UEQ)$.
\end{enumerate}

\subsection{Control-flow expressions}

This section covers how to check bounds declarations for expressions
with control flow: comma expressions, conditional expressions, and
logical boolean expressions.

For a comma expression $e1$~\lstinline|,|~$e2$, $Check(e, C, EQ, Form, FB)$ is defined as follows:
\begin{enumerate}
\item Let $(B_{e1}, \mathit{UC}_{e1}, {UEQ}_{e1}, \_, R_1, W_1)$ = $Check(e1, C, EQ, No, None)$
\item Let $(B, \mathit{UC}, UEQ, UG, R_2, W_2) = Check(e2, \mathit{UC}_{e1}, {UEQ}_{e1}, No, None)$
\item Let $R = R_1 \cup R_2$ and $W = W_1 \cup W_2$.
\end{enumerate}

For a conditional expression $e1$~\lstinline+?+~$e2$~\lstinline+:+~$e3$, we must
merge the results from both branches to produce a result for the entire expression.
This could lose information and cause checking to fail. For example,  the validity of bounds after
one arm could depend on assignments in that arm only.

We address this problem with the following approach:
\begin{itemize}
\item  If both arms produce the same updated context, we use that context
and merge the rest of the results.
\item If the arms produce different
contexts, we validate bounds declarations at the end of each arm.  We then
use the declared bounds in the updated context for the entire expression
and merge the result of the results.
\end{itemize}

Note that validating bounds after arms can be tricky.
A bounds declaration could depend on variables modified by an arm
and another expression whose evaluation is unordered with respect to the arm.
The side-effects in the unordered expression may not be reflected in the
context being validated.
One approach would be for $Check$ to produce two contexts,
one for each arm. This turn require that $Check$ take a set of contexts as
 inputs.  The number of contexts could grow exponentially.
To keep checking from becoming too expensive, we disallow such expressions.

\begin{enumerate}
\item Let $(\_, \mathit{UC}_{e1}, {UEQ}_{e1}, \_, RC, WC)= Check(e1, C, EQ, No, None)$
\item For each arm $e_i$ of the conditional branch,
        let $(B_i, \mathit{UC}_i, {UEQ}_i, G_i, R_i, W_i) = Check(e_i, \mathit{UC}_{e1}$, ${UEQ}_{e1}, No, None)$.
\item Handle uses of temporaries bound in only one branch.  These temporaries
will be uninitialized when the other branch of the conditional arm is evaluated.
If some $B_i$, $\mathit{UC}_i$ or ${UEQ}_i$ uses a temporary bound in $e_i$,
introduce a  temporary $r$ for the result of the entire conditional expression.
For each arm $e_i$ of the conditional branch, for each temporary $t$ bound
in only $e_i$ and used in $B_i$, $\mathit{UC}_i$ or ${UEQ}_i$,
\begin{enumerate}
\item See if $t$ is an element of $G_i$. If so, substitute $r$ for $t$ in $B_i$, $\mathit{UC}_i$ and ${UEQ}_i$,
and $G_i$.
\item Otherwise,
\begin{enumerate}
\item If $t$ is used by $B_i$, let $B_i = $ \boundsunknown.
\item For each variable $x$ where $t$ is used by $C_i[x]$, let $C_i = C_i[x \mapsto $\boundsunknown].
\item Let ${UEQ}_i = {UEQ}_i - \{ t \}$.
\end{enumerate}
\end{enumerate}
\item If the $\mathit{UC}_i$ are identical, let $\mathit{UC}$ = $\mathit{UC}_1$.
\item Otherwise,
\begin{enumerate}
\item Let $DC$ be the context formed from declared bounds.
Let $DC^\prime$ be $DC$ restricted to variables in $W_1 \cup W_2$:
for each variable $v \in dom(DC)$, keep the entry if $v \in W_1 \cup W_2$
or $DC[v]$ uses the value of a variable in $W_1 \cup W_2$.
\item For each arm $e_i$, call $Validate(DC^\prime, \mathit{UC}_i, {UEQ}_i)$.
\item Let $\mathit{UC} = \mathit{UC}_{e1}$.  Update $\mathit{UC}$ so that any variables modified by the conditional expression
have the top-level declared bounds (which were just validated after each arm).
For any variable $v$ in $DC^\prime$, let $\mathit{UC}[v] = DC^\prime[v]$.
\end{enumerate}
\item Let $B$ be the greatest lower bound of the $B_i$.
\item Let $UEQ = {UEQ}_1 \cap {UEQ}_2$,  where each set in $UEQ_1$ is intersected with each set in $UEQ_2$
to produce the set of sets.  Empty or singleton sets are removed.
\item Let $G = G_1 \cap G_2$.  If $e$ has no side-effects,add $\{ e \}$ to $G$.  If a
temporary was introduced for the value of $e$,  also add the temporary to $G$.
\item Let $R = RC \cup R_1 \cup R_2$.  Let $W = WC \cup W_1 \cup W_2$.
\item Make sure that all assignments to variables used in $DC^\prime$ have been seen before
validating $DC^\prime$ (otherwise the validation may be incorrect).
For each bounds expression $B$ in $DC^\prime$, let $Q$ by the variables read by $B$.
Let $R = R \cup Q$ (if an unordered assignment to a variable used in $Q$ is
subsequently processed, this will cause a checking failure).
\end{enumerate}

Logical boolean expressions are treated as forms of conditional expressions.
For  $Check(e1$ \code{&&} $ e2, C, Form, FB)$, use
$Check(e1$ \code{ ?  } $e2$ \code{: 0}$, C, EQ, Form, None)$.
For $Check(e1$ \code{ \|\| } $ e2, C, EQ, Form, FB)$,  use
$Check(e1 $ \code{ ? 1 : } $e2, C, EQ, No, None)$.

\subsection{Examples}

\subsubsection{Assignments separated by a comma operator}

The following example shows the steps of checking an assignment to an \arrayptr\ and its corresponding
length field, where the assignments are separated by a comma operator.  We assume that that the allocation
function returns an \arrayptrint\ to simplify the example.  Here is the code:
\begin{lstlisting}
array_ptr<int> alloc(int s) : count(s);

int len = 0;
array_ptr<int> x : count(len) = 0;
x = alloc(5), len = 5;
\end{lstlisting}

Here is a list of checking steps:
\begin{small}
\begin{tabbing}
~~~\=~~~\=~~~\=~~~\=~~~\=~~~\=~~~\=\\
$CheckFullExpr(e=$~\code{x = alloc(5)}\code{, len = 5}$)$\\
\>$DC = \{x \mapsto$\code{bounds(x, x + len)}$\}$\\
\>$Check(e=$~\code{x = alloc(5)}\code{, len = 5}$, C=\{x \mapsto$\code{bounds(x, x + len)}$\},  EQ=\emptyset,
           Form = No, FB = None)$\\
\>\>$Check(e=$~\code{x = alloc(5)}$,C=\{x\mapsto$\code{bounds(x,x + len)}$\},
                EQ=\emptyset, Form=No, FB=None)$ \\
  \>\>\>$CheckLValue($\code{x}$, C = \{x \mapsto$\code{bounds(x, x + len)}$\}, EQ = \emptyset)$ \\
  \>\>\>\>$(B = $ \code{bounds(&x, &x + 1)}, $RB = $\code{bounds(x, x + len)}$,
                           \mathit{UC} = \{x \mapsto$\code{bounds(x, x + len)}$\},$\\
  \>\>\>\>~$UEQ = \emptyset, G = \{$\code{&x}\}$, R = \emptyset, W = \emptyset)$ \\
  \>\>\>$Check($\code{alloc(5)}$,C  =\{x\mapsto$\code{bounds(x, x + len)}$\}, EQ = \emptyset, Form = No, FB = None)$\\
  \>\>\>\>$(B = $ \code{bounds(tmp, tmp + 5)}$, \mathit{UC} = \{x\mapsto$\code{bounds(x, x + len)}$ ,
              G = \{$\code{tmp}$\}, R = \emptyset, W = \emptyset)$\\
 \>\>\>$(B = $\code{bounds(tmp, tmp + 5)}$, \mathit{UC} = \{x\mapsto $\code{bounds(tmp, tmp + 5)}$\}, UEQ= \{\{tmp, x\}\},
          G = \{tmp, x\},$\\
  \>\>\>~$R = \emptyset, W = \{x\})$ \\
  \>\>$Check(e=$~\code{len = 5}$, C = \{x\mapsto $\code{bounds(tmp, tmp + 5)}$\}, UEQ= \{\{tmp, x\}\},
        Form = No, FB = None)$\\
   \>\>\>$CheckLValue($\code{len}$, C = \{x\mapsto $\code{bounds(tmp, tmp + 5)}$\}, UEQ= \{\{tmp, x\}\})$\\
   \>\>\>\>\>$(B = $ \code{bounds(&len, &len + 1)}$, RB = $\code{bounds(unknown)}$,$
                            $\mathit{UC} = \{x\mapsto $\code{bounds(tmp, tmp + 5)}$\},$\\
   \>\>\>\>\>~$UEQ = \{\{tmp, x\}\},  R = \emptyset, W = \emptyset)$\\
   \>\>\>$Check(e = $\code{5}, $\mathit{UC} = \{x\mapsto $\code{bounds(tmp, tmp + 5)}$\}, EQ = \{\{tmp, x\}\},
          Form = No, FB = None)$\\
   \>\>\>\>$(B = $ \code{bounds(unknown)}$, \mathit{UC} = \{x\mapsto $\code{bounds(tmp, tmp + 5)}$\},
            EQ = \{\{tmp, x\},\{5\}\},  G = \{5\},$\\
  \>\>\>\>~$R = \emptyset, W = \emptyset)$\\
   \>\>\>$(B = $ \code{bounds(unknown)}$, \mathit{UC} = \{x\mapsto $\code{bounds(tmp, tmp + 5)}$\},
             EQ = \{\{tmp, x\},\{5, len\}\},  G = \{5\},$\\
   \>\>\>~$R = \emptyset, W = \{ len \})$\\
   \>\>$(B = $ \code{bounds(unknown)}$, \mathit{UC} = \{x\mapsto $\code{bounds(tmp, tmp + 5)}$\},
             EQ = \{\{tmp, x\},\{5, len\}\},  G = \{5\},$\\
   \>\>~$R = \emptyset, W = \{ x, len \})$\\
  \>$Validate(DC = \{x \mapsto$\code{bounds(x, x + len)}$\},
                   \mathit{UC} = \{x\mapsto $\code{bounds(tmp, tmp + 5)}$\},
                   EQ = \{\{tmp, x\},\{5, len\}\})$\\
\end{tabbing}
\end{small}

\subsubsection{Assignments in a conditional expression}

There are two cases for checking conditional expressions. The first case is when the context is identical
at the end of both arms of a conditional expression. The second case is when the context differs.

Thus example shows assignments in a conditional expression that produce the same context at
the end of each arm.
\begin{lstlisting}
array_ptr<int> alloc(int c) : count(c);
int getlen(void);

int len = 0;
array_ptr<int> x : count(len) = 0;
x = (len = getlen()) ? alloc(len) : 0;
\end{lstlisting}

\begin{small}
\begin{tabbing}
~~~\=~~~\=~~~\=~~~\=~~~\=~~~\=~~~\=\\
$CheckFullExpr(e=$~\code{x = (len = getlen()) ? alloc(len) : 0}$)$\\
\>$DC = \{x \mapsto$\code{bounds(x, x + len)}$\}$\\
\>$Check(e=$~\code{x = (len = getlen()) ? alloc(len) : 0}$,$\\
\>\>\>\>~$C=\{x \mapsto$\code{bounds(x, x + len)}$\},EQ=\emptyset,
           Form = No, FB = None)$\\ \\

\>\>$CheckLValue($\code{x}$, C = \{x \mapsto$\code{bounds(x, x + len)}$\}, EQ = \emptyset)$ \\
\>\>\>\>\>$(B = $ \code{bounds(&x, &x + 1)}, $RB = $\code{bounds(x, x + len)}$,
                    \mathit{UC} = \{x \mapsto$\code{bounds(x, x + len)}$\}, R = \emptyset, W = \emptyset)$\\
\>\>$Check(e=$~\code{(len = getlen()) ? alloc(len) : 0}$,$\\
\>\>\>\>~$C=\{x \mapsto$\code{bounds(x, x + len)}$\},EQ=\emptyset,
           Form = No, FB = None)$\\ \\

% The condition expression
\>\>\>{\tt Process the condition:}\\
\>\>\>$Check(e=$~\code{(len = getlen())}$, C=\{x \mapsto$\code{bounds(x, x + len)}$\},
       EQ=\emptyset, Form = No,$\\
\>\>\>\>\>\>$FB = None)$\\
\>\>\>\>$Check(e=$~\code{len = getlen()}$, C=\{x \mapsto$\code{bounds(x, x + len)}$\},
         EQ=\emptyset, Form = No,$\\
\>\>\>\>\>\>\>$FB = None)$\\
\>\>\>\>\>$CheckLValue($\code{len}$, C = \{x \mapsto$\code{bounds(x, x + len)}$\}, EQ = \emptyset)$ \\
\>\>\>\>\>\>$(B = $ \code{bounds(&len, &len + 1)}, $RB = $\code{bounds(unknown)}$,
                     \mathit{UC} = \{x \mapsto$\code{bounds(x, x + len)}$\},$\\
\>\>\>\>\>\>~$UEQ = \emptyset, G = \{$\code{&len}\}$, R = \emptyset, W = \emptyset)$ \\
\>\>\>\>\>\>$Check($\code{getlen()}$,C  =\{x\mapsto$\code{bounds(x, x + len)}$\}, EQ = \emptyset,
                         Form = No, FB = None)$\\
\>\>\>\>\>\>$(B = $ \code{bounds(unknown)}$, \mathit{UC} = \{x\mapsto$\code{bounds(x, x + len)}$ , UEQ = \emptyset,
               G = \emptyset, R = \emptyset, W = \emptyset)$\\
\>\>\>\>\>$(B = $ \code{bounds(unknown)}$, \mathit{UC} = \{x\mapsto$\code{bounds(unknown)}$ , UEQ = \emptyset,
               G = \emptyset, R = \emptyset, W = \emptyset)$\\
\>\>\>\>$(B = $ \code{bounds(unknown)}$, \mathit{UC} = \{x\mapsto$\code{bounds(unknown)}$ , UEQ = \emptyset,
          G = \emptyset, R = \emptyset, W = \emptyset)$\\  \\
% first arm
\>\>\>{\tt Process the first arm:}\\
\>\>\>$Check(e=$~\code{alloc(len)}$, C=\{x \mapsto$\code{bounds(unknown)}$\},
         EQ=\emptyset, Form = No, FB = None)$\\
\>\>\>\>$(B_1 = $ \code{bounds(tmp1, tmp1 + len)}$, \mathit{UC}_1 = \{x\mapsto$\code{bounds(unknown)}$,
                {UEQ}_1 = \emptyset, G_1 = \{tmp1\}, R_1 = \emptyset, W_1 = \emptyset)$\\

% process the second arm
\\
\>\>\>{\tt Process the second arm:}\\
\>\>\>$Check(e=$~\code{0}$, C=\{x \mapsto$\code{bounds(unknown)}$\},
         EQ=\emptyset, Form = No, FB = None)$\\
\>\>\>\>$(B_2 = $ \code{bounds(any)}$, \mathit{UC}_2 = \{x\mapsto$\code{bounds(unknown)}$,
               {UEQ}_2 = \emptyset, G_2 = \{ 0 \}, R_2 = \emptyset, G_2 = \emptyset)$\\ \\

\>\>\>{\tt Adjust results for arms for temporaries. Introduce a new temporary tmp2 for the result of}\\
\>\>\>{\tt the entire conditional expression.}\\
\>\>\>\>$(B_1 = $\code{bounds(tmp2, tmp2 + len)}$, \mathit{UC}_1 = \{x\mapsto$\code{bounds(unknown)}$,
                {UEQ}_1 = \emptyset)$\\
\>\>\>\>$(B_2 = $ \code{bounds(any)}$, \mathit{UC}_2 = \{x\mapsto$\code{bounds(unknown)}$,$
               ${UEQ}_2 = \emptyset)$\\
\\
\>\>\>{\tt Merge information for arms:}\\
\>\>\>\>$(B = $\code{bounds(tmp2, tmp2 + len)}$, \mathit{UC} = \{x\mapsto$\code{bounds(unknown)}$,
                UEQ = \emptyset, G = \{ tmp2 \})$\\
\\
\>\>\>{\tt Result for assignment:}\\
\>\>\>$(B = $ \code{bounds(tmp2, tmp2 + len)}$, \mathit{UC} = \{x\mapsto$\code{bounds(tmp2, tmp2 + len)}$,$\\
\>\>\>\>~$UEQ = \{\{tmp2, x\}\}, G = \{tmp2 \})$\\
\\
\>\>$Validate(DC = \{x \mapsto$\code{bounds(x, x + len)}$\},
                   \mathit{UC} = \{x\mapsto $\code{bounds(tmp2, tmp2 + len)}$\},$\\
\>\>\>\>\>\>$EQ = \{\{tmp2, x\}\})$\\
\end{tabbing}
\end{small}

This example shows assignments within a conditional expression that cause the context to be
different.  In this case, the declared bounds for \lstinline+x+ must be valid after checking each arm
of the conditional  assignment.
\begin{lstlisting}
array_ptr<int> alloc(int c) : count(c);
int getlen(void);

int len = 0;
array_ptr<int> x : count(len) = 0;
(len = getlen()) ? (x = alloc(len)) : (len = 1, x = alloc(1));
\end{lstlisting}

\begin{small}
\begin{tabbing}
~~~\=~~~\=~~~\=~~~\=~~~\=~~~\=~~~\=\\
$CheckFullExpr(e=$~\code{(len = getlen()) ? (x = alloc(len)) : (x = alloc(1), len = 1)}$)$\\
\>$DC = \{x \mapsto$\code{bounds(x, x + len)}$\}$\\
\>$Check(e=$~\code{(len = getlen()) ? (x = alloc(len)) : (x = alloc(1), len = 1)}$,$\\
\>\>\>\>~$C=\{x \mapsto$\code{bounds(x, x + len)}$\},EQ=\emptyset,
           Form = No, FB = None)$\\ \\
% The condition expression
\>\>{\tt Process the condition:}\\
\>\>$Check(e=$~\code{(len = getlen())}$, C=\{x \mapsto$\code{bounds(x, x + len)}$\},
       EQ=\emptyset, Form = No,$\\
\>\>\>\>\>$FB = None)$\\
\>\>\>$Check(e=$~\code{len = getlen()}$, C=\{x \mapsto$\code{bounds(x, x + len)}$\},
         EQ=\emptyset, Form = No,$\\
\>\>\>\>\>\>$FB = None)$\\
\>\>\>\>$CheckLValue($\code{len}$, C = \{x \mapsto$\code{bounds(x, x + len)}$\}, EQ = \emptyset)$ \\
\>\>\>\>\>$(B = $ \code{bounds(&len, &len + 1)}, $RB = $\code{bounds(unknown)}$,
                     \mathit{UC} = \{x \mapsto$\code{bounds(x, x + len)}$\},$\\
\>\>\>\>\>~$UEQ = \emptyset, G = \{$\code{&len}\}$, R = \emptyset, W = \emptyset)$ \\
\>\>\>\>$Check($\code{getlen()}$,C  =\{x\mapsto$\code{bounds(x, x + len)}$\}, EQ = \emptyset,
                         Form = No, FB = None)$\\
\>\>\>\>\>$(B = $ \code{bounds(unknown)}$, \mathit{UC} = \{x\mapsto$\code{bounds(x, x + len)}$ , UEQ = \emptyset,
               G = \emptyset, R = \emptyset, G = \emptyset)$\\
\>\>\>\>$(B = $ \code{bounds(unknown)}$, \mathit{UC} = \{x\mapsto$\code{bounds(unknown)}$ , UEQ = \emptyset,
               G = \emptyset, R = \emptyset, W = \{$\code{len}$\})$\\
\>\>\>$(B = $ \code{bounds(unknown)}$, \mathit{UC} = \{x\mapsto$\code{bounds(unknown)}$ , UEQ = \emptyset,
          G = \emptyset, R = \emptyset, W = \{$\code{len}$\})$\\  \\
% first arm
\>\>{\tt Process the first arm:}\\
\>\>$Check(e=$~\code{(x = alloc(len))}$, C=\{x \mapsto$\code{bounds(unknown)}$\},
         EQ=\emptyset, Form = No, FB = None)$\\
\>\>\>$Check(e=$~\code{x = alloc(len)}$, C=\{x \mapsto$\code{bounds(unknown)}$\},
          EQ=\emptyset, Form = No, FB = None)$\\
\>\>\>\>$CheckLValue($\code{x}$, C = \{x \mapsto$\code{bounds(unknown)}$\}, EQ = \emptyset)$ \\
\>\>\>\>\>$(B = $ \code{bounds(&x, &x + 1)}, $RB = $\code{bounds(unknown)}$,
                     \mathit{UC} = \{x \mapsto$\code{bounds(x, x + len)}$\},$\\
\>\>\>\>\>~$UEQ = \emptyset, G = \{$\code{&x}\}$)$ \\
\>\>\>$Check($\code{alloc(len)}$,C  =\{x\mapsto$\code{bounds(unknown)}$\}, EQ = \emptyset,
                       Form = No, FB = None)$\\
\>\>\>\>$(B = $ \code{bounds(tmp1, tmp1 + len)}$, \mathit{UC} = \{x\mapsto$\code{bounds(unknown)}$,
                UEQ = \emptyset G = \{tmp1\})$\\
\>\>\>$(B = $ \code{bounds(tmp1, tmp1 + len)}$, \mathit{UC} = \{x\mapsto$\code{bounds(tmp1, tmp1 + len)}$ ,
             UEQ = \{\{x, tmp1\}\},$\\
\>\>\>~$G = \{x, tmp1\})$\\ \\
% process the second arm
\>\>{\tt Process the second arm:}\\
\>\>$Check(e=$~\code{((len = 1, x = alloc(1))}$, C=\{x \mapsto$\code{bounds(unknown)}$\},
         EQ=\emptyset, Form = No,$\\
\>\>\>\>\>$FB = None)$\\
\>\>\>$Check(e=$~\code{len = 1, x = alloc(1)}$, C=\{x \mapsto$\code{bounds(unknown)}$\},
          EQ=\emptyset, Form = No,$\\
\>\>\>\>\>\>$FB = None)$\\
\>\>\>\>$Check(e=$~\code{len = 1}$, C=\{x \mapsto$\code{bounds(unknown)}$\},
          EQ=\emptyset, Form = No, FB = None)$\\
\>\>\>\>\>$CheckLValue($\code{len}$, C = \{x \mapsto$\code{bounds(unknown)}$\}, EQ =  \emptyset)$ \\
\>\>\>\>\>\>$(B = $ \code{bounds(&len, &len + 1)}, $RB = $\code{bounds(unknown)}$,
                     \mathit{UC} = \{x \mapsto$\code{bounds(unknown)}$\},$\\
\>\>\>\>\>\>~$UEQ =  \emptyset, G = \{$\code{&len}\}$)$ \\
\>\>\>\>\>$Check($\code{1}$,C  =\{x\mapsto$\code{bounds(unknown)}$\}, EQ = \emptyset,
                       Form = No, FB = None)$\\
\>\>\>\>\>\>$(B = $ \code{bounds(unknown)}$, \mathit{UC} = \{x\mapsto$\code{bounds(unknown)}$,
                  UEQ = \emptyset, G = \{1\})$\\
\>\>\>\>\>$(B = $ \code{bounds(unknown)}$, \mathit{UC} = \{x\mapsto$\code{bounds(unknown)}$,
                  UEQ = \{\{len, 1\}\}, G = \{len, 1\})$\\
\>\>\>\>$Check(e=$~\code{x = alloc(1)}$, C=\{x \mapsto$\code{bounds(unknown)}$\},
          EQ=\{\{len, 1\}\}, Form = No,$\\
\>\>\>\>~$FB = None)$\\
\>\>\>\>\>$CheckLValue($\code{x}$, C = \{x \mapsto$\code{bounds(unknown)}$\},
                                      EQ = \{\{len, 1\}\})$ \\
\>\>\>\>\>\>$(B = $ \code{bounds(&x, &x + 1)}, $RB = $\code{bounds(unknown)}$,
                     \mathit{UC} = \{x \mapsto$\code{bounds(unknown)}$\},$\\
\>\>\>\>\>\>~$UEQ = \{\{len, 1\}\}, G = \{$\code{&x}\}$)$ \\
\>\>\>\>\>$Check($\code{alloc(1)}$,C  =\{x\mapsto$\code{bounds(unknown)}$\}, EQ = \{\{len, 1\}\},
                       Form = No, FB = None)$\\
\>\>\>\>\>\>$(B = $ \code{bounds(tmp2, tmp2 + 1)}$, \mathit{UC} = \{x\mapsto$\code{bounds(unknown)}$,
                      UEQ = \{\{len, 1\}\},G = \{tmp2\})$\\
\>\>\>\>\>$(B = $ \code{bounds(tmp2, tmp2 + 1)}$,
                   \mathit{UC} = \{x\mapsto$\code{bounds(tmp2, tmp2 + 1))}$,$\\
\>\>\>\>\>~UEQ = \{\{len, 1\}, \{x, tmp2\}\},$G = \{x, tmp2\})$\\
\>\>\>\>$(B = $ \code{bounds(tmp2, tmp2 + 1)}$, \mathit{UC} = \{x\mapsto$\code{bounds(tmp2, tmp2 + 1))}$,$\\
\>\>\>\>~$UEQ = \{\{len, 1\}, \{x, tmp2\}\}, G = \{x, tmp2\})$\\
\>\>\>$(B = $ \code{bounds(tmp2, tmp2 + 1)}$, \mathit{UC} = \{x\mapsto$\code{bounds(tmp2, tmp2 + 1))}$,$\\
\>\>\>~$UEQ = \{\{len, 1\}, \{x, tmp2\}, G = \{x, tmp2\})$\\ \\
% Contexts are not the same, so validate results after each arm.
\>\>{\tt Contexts are not the same, so validate contexts after each arm:}\\
\>\>$Validate(DC = \{x \mapsto$\code{bounds(x, x + len)}$\},
                   \mathit{UC} = \{x\mapsto $\code{bounds(tmp1, tmp1 + len)}$\},$\\
\>\>\>\>\>\>$EQ = \{\{tmp1, x\}\})$\\
\>\>$Validate(DC = \{x \mapsto$\code{bounds(x, x + len)}$\},
                   \mathit{UC} = \{x\mapsto $\code{bounds(tmp2, tmp2 + 1)}$\},$\\
\>\>\>\>\>\>$EQ = \{\{len, 1\}, \{x, tmp2\}\})$\\
\end{tabbing}
\end{small}

\subsection{Different orders of recursive calls produce the same result}

The pending variable sets used in recursive calls to $Check$ and $CheckLValue$
ensure that updates to the context and sets of equivalent expressions are done on different variables when
the order of evaluation is not specified.  This in turn ensures that the the same context and sets of equivalent expressions
are produced no matter which order the recursive calls are made.   Here we informally argue
that this property (known as confluence) holds for assignments that have the form $lhs = rhs$.

Suppose that $lhs$
contains a single assignment expression that updates a variable $v$ with an expression $e1$ and
$rhs$ contains a single assignment expression that updates  a variable $w$ with an expression $e2$.
We assume that $lhs$ does not update or use $w$ and that $rhs$ does not use or update $v$
(if either did, this leads to an error being reported no matter which order recursive calls are
made because of the pending variable sets.  $w$ appears in the pending variable set for
$CheckLValue(lhs,\ldots)$ and $v$ appears in the pending variable set for $Check(rhs, \ldots)$).

Observe that a recursive call to $Check(e, \ldots)$ or $CheckLValue(e, \ldots)$ only updates the context
and the sets of equivalent expressions for variables that are assigned to in $e$.   $CheckLValue(lhs,\ldots)$ and
$Check(rhs, \ldots)$ have assignments to different sets of variables because of the $Pending$ sets.  This
implies that $CheckLValue(lhs,\ldots)$ and $Check(rhs, \ldots)$ only do updates for different variables.

We want to show this leads to the same context and sets of equivalent expressions no matter which order
$CheckLValue$ and $Check$ are called.  We consider the case where  $CheckLValue(lhs, \ldots)$
is called first. There are two possible kinds of updates in $CheckLValue$ for the assignment to $v$.
\begin{itemize}
\item Replace occurrences of $v$ in expressions in the context and sets of equivalent expressions with the
expression $inverse(e1, v)$, which computes the prior value of $v$ based on the current value of $v$.
Now, $e1$ cannot use $w$, because that would result in $CheckLValue$ reporting an error.
$inverse(e1, v)$ does
not introduce any new uses of variables not in $e1$ so $inverse(e1, v)$ cannot use $w$ either.
After $inverse(e1, v)$ is substituted for $v$ in the context
or the sets of equivalent expressions during $CheckLValue(lhs, \ldots)$, each substituted expression will be
unchanged by the call to $Check(rhs, \ldots)$.  This is because the only updates done by
$Check(rhs, \ldots)$ involve $w$.

$CheckLValue(lhs, \ldots)$ does not affect any occurrences of $w$.  Those will be replaced
by $inverse(e2, w)$ in the call to $Check(rhs, \ldots)$.

\item Replace the bounds expression for $v$ in the context with a new bounds expression $b$.
When $Check$ infers the bounds for $e1$, $e1$ cannot use $w$ because that would result in
$Check$ reporting an error. This means that the only way a use of $w$ can appear in $b$ is
through a look up of bounds of some variable $y$ in the context (note that $y$ could be
$v$ or $w$).

There are several cases possible for $y$:
\begin{itemize}
\item There is no assignment to $y$ in $lhs$ or $rhs$.   In that case, the bound of $y$
must be $C[y]$, where $C$ is the context passed into $CheckLValue$.  We are in the midst
of processing the assignment $v = e1$ and the assignment $w = e2$ have not been processed yet.

The bounds $C[y]$ are  either propagated or dropped during the computation of bounds for $e1$.
If the bounds $C[y]$ are dropped, then they cannot be the source of $w$.  So the bounds $C[y]$ must be propagated.  During propagation, $inverse(e1, v)$ will be substituted for $v$.  No change can happen to the occurrence of $w$ because there are no assignments to $w$
in $CheckLValue(lhs, \ldots)$.  Now, when $Check(rhs, \ldots)$ is called, there will be no changes in the
context to the substituted expression $inverse(e1, v)$ because $w$ cannot occur in $e1$.
The occurrence of $w$ in the bounds for $v$ will be updated by $Check(rhs, \ldots)$ to $inverse(e2, w)$.
Note that $inverse(e2, w)$ cannot contain a use of $v$.

Now, if $Check(rhs, \ldots)$ is called first, the bounds for $y$ in the context will be updated to use
$inverse(e2, w)$ in place of $w$.  Each substituted expression will be left unchanged as the bounds
propagate in the call to $CheckLValue$.  $e2$ cannot use $v$, so $inverse(e2, w)$ will not use $v$.

\item There is an assignment to $y$ in $lhs$ or $rhs$.   The case where there is an assignment
to $y$ in the $rhs$ is not possible because that would create an unordered read and write of $y$.
$y$ can also not be assigned within $e1$ for a similar reason.  That leaves just one case: $y$ is
assigned to after $e1$ is evaluated.  This means that the bounds of $y$ must be $C[y]$.   The logic
regarding propagating bounds from the prior case can be applied to show that the order of
assignments does not matter.
\end{itemize}
\end{itemize}

Similar reasoning applies when $Check$ is called before $CheckLValue$. Thus, we have shown that
checking an assignment expression produces the same result, no matter which order $Check$ and
$CheckLValue$ are called.

Similar reasoning also applies when there are multiple recursive calls to
$Check$ (as happens in case~\ref{list:check-unordered-operands} of $Check$ and
case~\ref{list:check-unordered-subscript-operands} of $CheckLValue$).  Thus, we argue
that checking expressions with subexpressions whose evaluation is unordered with
respect to one another produces the same result, no matter which order $Check$
or $CheckLValue$ are invoked recursively on the subexpressions.

\section{Checking that full expressions maintain declared bounds}
\label{section:checking-full-expressions}

We need to check that full expressions mantain the validity of
declared bounds.  If a full expression is within a
bundled block, the checking is deferred to the end of the bundled block.

To check a full expression, the analysis of
Section~\ref{section:extent-definition} is used
to determine the context for the full expression (the bounds
for variables before the expression is evaluated). The $Check$
method in Section~\ref{section:checking-complex-expressions}
is then used to determine the updated context and sets of equivalente expressions.

The updated context is then checked against the bounds declarations that
must be true after the expression statement. For each
\arrayptr\ variable \var{x} in scope, the expected bounds is
computed:

\begin{itemize}
\item
  If the expression statement has a bounds declaration for \var{x}, the
  bounds expression in that bounds declaration is used.
\item
  Otherwise, the analysis of Section~\ref{section:extent-definition}
  is used to determine the
  expected bounds expression for x.
\end{itemize}

The bounds expression for \var{x} in the updated context
is called the updated bounds expression.  It must imply that the
expected bounds expression holds. Implication is checked in this section
by placing bounds expressions into a canonical form and
checking for syntactic equality, taking into account sets
of expressions that are equivalent after the expression has
been evaluated.  Chapter~\ref{chapter:simple-invariants}
describes more general techniques for checking
that context bounds imply the expected bounds.

An updated bounds expression implies that the expected bounds
expression holds if:

\begin{itemize}
\item
  The expected bounds expression is \boundsunknown, or
\item
  The updated bounds expression is \boundsany, or
\item
  The updated bounds expression and the expected bounds expression are
  equal syntactically after placing the expressions into canonical
  forms, taking into sets of expressions that are equivalent after the full
  expression,
\item
  The canonicalized expressions
  differ syntactically only in their relative alignment, and
  the context bounds implies the expected relative alignment \var{c}.
  This is true if:

  \begin{itemize}
  \item
    The context relative alignment is an integer multiple of the
    expected relative alignment,
  \item
   or given a context bounds expression of the form
   \boundsrel{\var{e1}}{\var{e2}}{\var{d}},
   \texttt{(\cast{\arrayptrchar}{\var{x}} - \cast{\arrayptrchar}{\var{e1}}) \% \var{c}}
   canonicalizes to \code{0}, as does
   \texttt{(\cast{\arrayptrchar}{\var{e2}} - \cast{\arrayptrchar}{\var{x}}) \% \var{c}}.
  \end{itemize}
\end{itemize}

\subsection{Canonicalization of expressions in bounds expressions}
\label{section:canonicalization}

Most readers can skip this section safely and come back to it as
necessary. This section is for compiler implementers and for programmers
who want to understand when expressions are regarded as identical by
canonicalization.

Canonicalization guarantees the following: if two non-modifying
expressions have the same canonical form and if they produce values when
evaluated at runtime, the two values will be equal. There are two
important things to understand about this definition. First, two C
expressions may have different canonicalized forms and still always
produce the same value at runtime (in the terminology of logic,
canonicalization is incomplete). Second, canonicalization does not
guarantee that an expression will actually produce a value at runtime.
It may still have a runtime fault. The runtime correctness of bounds
expressions is implied by transitivity: a bounds expression must be
implied by another bounds expression, and so on, until a bounds
expression is implied by an allocation. The allocation must have
involved an expression that actually produced a value.

This has a surprising consequence: integer arithmetic operations that
check for overflow can be regarded as following mathematical rules
during canonicalization. A compiler could not reassociate \texttt{((a
\plusovf\ b) \plusovf\ c)} to \texttt{(a
\plusovf\ (b \plusovf\ c)} and replace the first
expression with the second one because it could cause an overflow where
none occurred before. For canonicalization, though, reassociation is
fine.

Signed integer operations do not follow certain mathematical identities.
This is because according to the rules in
Section~\ref{section:changes-to-undefined-behavior}, they may produce
a value on overflow, but the properties of the value are not specified.
Signed addition is not associative: \code{(a + b) + c} is not
guaranteed to produce the same result as \code{a + (b + c)} in the
presence of overflow. The expression \code{a + b} may overflow, while
\code{b + c} may not overflow or the reverse may occur. In addition,
for signed integers, it is not guaranteed that \code{a - b} =
\code{a + (-b)} or that \code{-(-(a))} = \code{a}.

The canonicalization rules need to disambiguate between signed and
unsigned operators for integers, as well as operators that check for
overflow. All integer operators will be subscripted by whether they
apply to signed or unsigned integers and whether they check overflow
using the subscripts \code{signed}, \code{unsigned}, and
\code{ovf}. For example, the expression \code{(a + b) + c} involving
signed integers will be written as \texttt{(a
+}\emph{\textsubscript{signed}} \texttt{b)
+}\emph{\textsubscript{signed}} \texttt{c}.

The overflow checking operators introduced in
Section~\ref{section:pointers-as-integers} only include
operators that can occur in practice. For canonicalization, it is useful
to have a complete set of operators, including
\plusovf\ and \minusovf\ that
take two integers (both signed or unsigned) and produce an integer that
has the same type as the arguments, as well as unary negation that takes
a signed or unsigned integer and produces a signed integer.

In the rules for canoncialization, when a subscript on an integer
operator is omitted, the rule applies to all forms of the operator.
Sometimes the subscript \var{kind} will be used on operators. Either
\code{unsigned} or \code{ovf} should be substituted for \var{kind}
in the rule.

The first step in canonicalization is to convert non-modifying
expressions to an initial representation:

\begin{compactenum}
\item
  All expressions involving operators are fully parenthesized and
  unnecessary parenthesis on variables and constants are removed. For
  example, \var{e1} \var{op1} \var{e2} \var{op2} \var{e3}, is
  replaced by \texttt{((}\var{e1} \var{op1} \var{e2}\texttt{)}
  \var{op2} \var{e3}\texttt{)} or \texttt{(}\var{e1} \var{op1}
  \texttt{(}\var{e2} \var{op2} \var{e3}\texttt{))}, depending on the
  precedence of \var{op1} and \var{op2}.
\item
  Implicit cast operations are made explicit.
\item
  The pointer dereference \code{*} and pointer indirection operators
  \code{(->)} are implicitly annotated with their pointer types.
  This is necessary because converting pointer arithmetic to integer
  arithmetic will erase the type information needed by these operators.
\item
  Unary plus operations are removed.
\item
  Array references of the form
  \var{e1}\code{[}\var{e2}\code{]} are converted to
  \code{*((}\var{e1}\code{)} \code{+}
  \code{(}\var{e2}\code{))}
\item
  Pointer arithmetic is expanded to integer-based arithmetic.
\item
  Binary subtraction expressions are canonicalized to use unary minus
  when possible: \var{e1} \code{-}\emph{\textsubscript{kind}}
  \var{e2} is converted to \var{e1}
  \code{+}\emph{\textsubscript{kind}}
  \code{-}\emph{\textsubscript{kind} e2}.
\end{compactenum}

For the second step of canonicalization, two sets of binary arithmetic
operators are defined

\begin{compactitem}
\item
  The set of commutative and associative operators (CA operators).
  This includes:

  \begin{itemize}
  \item
    The operators +\texttt{\textsubscript{unsigned}},
    \texttt{*\textsubscript{unsigned}}, \plusovf\,
    and \mulovf\.
  item
    The bitwise operators \lstinline@|@, \code{&}, and
    \code{^}.
  \item
    The Boolean operators \lstinline@||@ and \code{&&}.
  \end{itemize}
\item
  The set of commutative-only operators (CO):
  \texttt{+\textsubscript{signed}} and \texttt{*\textsubscript{signed}}.
\end{compactitem}

The following rules are applied until no further changes occur:

\begin{compactenum}
\item
  Removing pointer casts and identity casts on integral types (casts
  from a type to itself). Pointer casts do not change the values of
  pointers.
\item
  Folding constant integral expressions. The following expressions are
  constant-folded:

  \begin{compactenum}
  \item
    Any constant expression that uses only overflow-checking arithmetic
    operators and that mathematically evaluates to an in-range integer
    value. The value is the mathematical result.
  \item
    Any constant expression involving integers that produces a defined
    result according to the C language standard or the C implementation
    rules.
  \end{compactenum}
\item
  Applying algebraic identities to simplify expressions

  \begin{compactenum}
  \item
    Arithmetic identities

    \begin{compactenum}
    \item
      \var{e} \code{+ 0 =} \var{e}, \var{e} \code{- 0 =} \var{e},
      \code{0 -} \var{e} =
      \code{(-}\var{e}\code{)}, \code{0 *} \var{e} = \code{0},
      \code{1 *} \var{e} = \var{e},
      \var{e} \code{/ 1} = \var{e},
      \var{e} \code{/ -1} = \code{-}\var{e},
      \var{e} \lstinline|% 1| = \var{e}
    \item
      For a positive constant \var{c}, (\var{e}
      \code{*}\emph{\textsubscript{kind}} \var{c}) \lstinline|%|
      \var{c} = \code{0}
    \end{compactenum}
  \item
    Bitwise identities: \var{e} \code{&} \code{0} = \code{0},
    \var{e} \lstinline@|@ \code{0} = \var{e}, \var{e}
    \lstinline|^| \code{0} = \var{e}, and
    \lstinline|~(~|\var{e}|\lstinline|))| =
    \var{e}
  \item
    Boolean identities: given a non-zero constant c, \var{e}
    \code{&&} \var{c} simplifies to \var{e}, \var{e}
    \lstinline@||@ \var{c} simplifies to \code{1}, and
    \code{!}\var{c} = \emph{0}. When \var{c} = \code{0}, \var{e}
    \code{&&} \var{c} simplifies to \code{0}, \var{e}
    \lstinline@||@ \var{c} simplifies to \var{e}, and
    \code{!}\var{c} = \code{1}.
  \item
    Double negation:
    \code{-}\emph{\textsubscript{kind}}(\code{-}\emph{\textsubscript{kind}}
    \var{e}\code{)} = e.
  \item
    Cancelling terms: \var{e} \code{-}\textsubscript{signed} \var{e}
    simplifies to \code{0} and \var{e} \texttt{+\textsubscript{kind}}
    (\texttt{-\textsubscript{kind}} \var{e}) simplifies to \code{0}.
    This is applied more generally to a sequence of addition operations
    of the form \texttt{(}\ldots{} \texttt{(}e1
    \texttt{+}\textsubscript{kind} e2\texttt{)} \ldots{}
    \texttt{+}\textsubscript{kind} \texttt{-}\emph{\textsubscript{kind}}
    e1 \ldots{}\texttt{)}.

    When identities have commutative versions, those are applied as
    well.
  \end{compactenum}
\item
  Applying associativity commutivity, and distributivity rules to put
  expressions in canonical forms:
\begin{compactenum}
\item
  For each operator \var{op} in CA, repeatedly rewriting any expression
  of the from \var{e1} \var{op} \code{(}\var{e2} \var{op}
  \var{e3}\code{)} to \code{(}\var{e1} \var{op}
  \var{e2}\code{)} \var{op} \var{e3} until no further rewrites are
  possible.
\item
  For each operator \var{op} in CA, for each sequence of operations
  (\ldots{} ((\var{e1} \var{op} \var{e2}) \var{op} \var{e3})
  \ldots{} \var{op} \var{en}), reordering the operands so that
  \var{e1} \ldots{} \var{en} appear in lexicographic order. Constants
  should appear lower in the lexicographic order than more complex
  expressions.
\item
  For each operator \var{op} in CO, commuting the operands in \var{e1}
  \var{op} \var{e2} so that \var{e1} is lower in the lexicographic
  order.
\item
  Applying the following distributivity rules:

  \begin{compactenum}
  \item
    Rewriting \code{-}\emph{\textsubscript{kind}}\code{(}\var{e1}
    \code{+}\emph{\textsubscript{kind}} \var{e2}\code{)} to
    \code{(-}\emph{\textsubscript{kind} e1}\code{)} \code{+}
    \code{(-}\emph{\textsubscript{kind} e2}\code{)},
  \item
    Rewriting \code{(}\var{e1} \code{+}\emph{\textsubscript{kind}}
    \var{e2}\code{)} \code{*}\emph{\textsubscript{kind}} \var{e3}
    to \code{(}\var{e1} \code{*}\emph{\textsubscript{kind}}
    \var{e3}\code{)} \code{+}\emph{\textsubscript{kind}}
    \code{(}\var{e2} \code{*}\emph{\textsubscript{kind}}
    \var{e3}\code{)}
  \item
    Rewriting \code{(}\var{e1} \lstinline@|@ \var{e2}\code{)} \lstinline@&@ \var{e3} as
    \code{(}\var{e1} \lstinline@&@ \var{e3}\code{)} \lstinline@|@ \code{(}\var{e2}
    \lstinline@&@ \var{e3}\code{)} and
    rewriting \var{e3} \lstinline@&@ \code{(}\var{e1} \lstinline@|@ \var{e2}\code{)} as
    \code{(}\var{e3} \lstinline@&@ \var{e1} \lstinline@|@ \var{e3} \lstinline@&@ \var{e2}\code{)}
  \item
    Rewriting !(\var{e1} \lstinline@||@ \var{e2}) as ((!\var{e1}) \lstinline@&&@ (!\var{e2})) and
    !(\var{e1} \lstinline@&&@ \var{e2}) as ((!\var{e1}) \lstinline@||@ (!\var{e2}))
  \item
    Rewriting (\var{e1} \lstinline@||@ \var{e2}) \lstinline@&&@ \var{e3} as
    (\var{e1} \lstinline@&&@ \var{e3})
    \lstinline@||@ (\var{e2} \lstinline@&&@ \var{e3}) and rewriting \var{e3} \lstinline@&&@ (\var{e1}
    \lstinline@||@ \var{e2}) as (\var{e3} \lstinline@&&@ \var{e1} \lstinline@||@ \var{e3}
    \lstinline@&&@ \var{e2})
  \end{compactenum}
\end{compactenum}
\end{compactenum}

The distributivity rules expand the size of expressions, potentially
increasing size exponentially. Implementations may have a reasonable
limit on the size of canonicalized expressions. A minimum required limit
will be determined based on an empirical evaluation of C programs.

\subsection{An example of canonicalization}
\label{section:canonicalization-example}

Here is how bounds for the following declaration and statement will be checked:
\begin{lstlisting}
array_ptr<int> x;
x = malloc(sizeof(int)*5) where x : count(5);
\end{lstlisting}

The function \lstinline+malloc+ is assumed to have the bounds declaration:

\begin{lstlisting}
array_ptr<void> malloc(size_t num) : byte_count(num);
\end{lstlisting}

even though in practice it will have a bounds-safe interface that does
not use a checked pointer type.

First, the implicit casts are made explicit and count is expanded to bounds:

\begin{lstlisting}
x = (array_ptr<int>) malloc(sizeof(int)*(size_t) 5) where x : bounds(x, x + 5);
\end{lstlisting}

Next, the bounds for the right-hand expression are computed. The bounds
declaration for malloc is expanded to:
\begin{lstlisting}
array_ptr<void> malloc(size_t num)
where return_value : bounds((array_ptr<char>) return_value,
                            (array_ptr<char>) return_value + num)
\end{lstlisting}

The bounds for malloc are used to compute the bounds for the function
call \lstinline+malloc(sizeof(int)*(size_t) 5)+. The actual argument
\lstinline+sizeof(int)*(size_t) 5+ is substituted for \lstinline+num+ in the
bounds expression for the return value of \lstinline+malloc+:
\begin{lstlisting}
return_value : bounds((array_ptr<char>) return_value,
                      (array_ptr<char>) return_value + sizeof(int)*(size_t) 5)
\end{lstlisting}

Next, \lstinline+expr_current_value+ is substituted for \lstinline+return_value+ :
\begin{lstlisting}
expr_current_value :
  bounds((array_ptr<char>) expr_current_value,
         (array_ptr<char>) expr_current_value + sizeof(int)*(size_t) 5)
\end{lstlisting}

Then, the bounds for \lstinline|(array_ptr<int>) malloc(sizeof(int)*(size_t) 5)|
are computed. The inverse cast \lstinline|(array_ptr<void> expr_current_value)|
is substituted for \lstinline|expr_current_value|:

\begin{lstlisting}
expr_current_value :
  bounds((array_ptr<char>) ((array_ptr<void>) expr_current_value),
         (array_ptr<char>) ((array_ptr<void>) expr_current_value) +
                               sizeof(int) * (size_t) 5)
\end{lstlisting}

Finally, \lstinline|x| is substituted for \lstinline|expr_current_value| :

\begin{lstlisting}
x : bounds((array_ptr<char>) ((array_ptr<void>) x),
           (array_ptr<char>) ((array_ptr<void>) x) +
                                sizeof(int) * (size_t) 5)
\end{lstlisting}

Now, it has be shown that the computed bounds for \lstinline|x|\ imply the expected
bounds for \lstinline|x|\ of \lstinline|bounds(x, x + 5)|. The bounds expressions are both
converted to use integer arithmetic:

\begin{lstlisting}[escapechar=\@]
// computed bounds
bounds((array_ptr<char>) ((array_ptr<void>) x),
       (array_ptr<char>) ((array_ptr<void>) x) @+\textsubscript{ovf}@
                             sizeof(int)@*\textsubscript{unsigned}@(size_t) 5))
// expected bounds
bounds(x, x @+\textsubscript{ovf}@ (5 @*\textsubscript{ovf}@(signed_size_t) sizeof(int)))
\end{lstlisting}

Next, unnecessary pointer casts are removed:
\begin{lstlisting}[escapechar=\@]
// computed bounds
bounds(x, x @+\textsubscript{ovf}@ (sizeof(int) @*\textsubscript{unsigned}@ (size_t) 5))
// expected bounds
bounds(x, x @+\textsubscript{ovf}@ (5 @*\textsubscript{ovf}@ (signed_size_t) sizeof(int)))
\end{lstlisting}

After that, constant folding is done. If \lstinline+sizeof(int)+ is 4, the result is:
\begin{lstlisting}[escapechar=\@]
// computed bounds
bounds(x, x @+\textsubscript{ovf}@ 20)
// expected bounds
bounds(x, x @+\textsubscript{ovf}@ 20)
\end{lstlisting}

We must also show the expected bounds imply that the
\lstinline|rel_align(int)| requirement is met. This is straightforward for
a constant-sized array. It involves showing given the variable \lstinline+x+ with
\bounds{\var{e1}}{\var{e2}} that
\lstinline[mathescape]|((array_ptr<char>) x - (array_ptr<char>) $\var{e1}$) % 4| canonicalizes
to 0, as does \lstinline[mathescape]|((array_ptr<char> $\var{e2}$ - (array_ptr<char>) x) \% 4|.

For the first expression, \lstinline|((array_ptr<char>) x - (array_ptr<char>) x) % 4|
simplifies to \lstinline|0 % 4|, which constant-folds to \lstinline|0|.
For the second expression, \lstinline|((array_ptr<char>) (x + 5) - (array_ptr<char>) x) % 4|
simplifies to
\lstinline[mathescape]|((x $\texttt{+}\textsubscript{ovf}$ 20) $\texttt{-}\textsubscript{ovf\_diff}$ x) % 4|.
This simplifies to \lstinline|20 % 4|, which constant-folds to \lstinline|0|.

If we change the example to make the number of elements variable instead
of constant, we can see how canonicalization breaks down in the presence
of integer wraparound. Suppose the number of elements is given by a
variable \lstinline|k|. We would have:

\begin{lstlisting}[escapechar=\@]
// computed bounds
bounds(x, x @+\textsubscript{ovf}@ (sizeof(int) @*\textsubscript{unsigned}@ (size_t) k))
// expected bounds
bounds(x, x @+\textsubscript{ovf}@ (k @*\textsubscript{ovf}@ (signed_size_t) sizeof(int)))
\end{lstlisting}

After converting pointer arithmetic to integer arithmetic, we have:
\begin{lstlisting}[escapechar=\@]
// computed bounds
bounds(x, x @+\textsubscript{ovf}@ (4 @*\textsubscript{unsigned}@ (size_t) k))
// expected bounds
bounds(x, x @+\textsubscript{ovf}@ (k @*\textsubscript{ovf}@ 4))
\end{lstlisting}

Canonicalization of the upper bounds expressions produces:
\begin{lstlisting}[escapechar=\@]
// computed bounds
x @+\textsubscript{ovf}@ (4 @*\textsubscript{unsigned}@ (size_t) k))
// expected bounds
x @+\textsubscript{ovf}@ (4 @*\textsubscript{ovf}@ k)
\end{lstlisting}

The expressions are not identically syntactically, so bounds expression
checking fails. The additional side conditions that \lstinline|k >= 0 && k <= UINTPTR_MAX/4|
are needed to show that the computed upper bound implies the expected upper bound. More
general techniques from Chapter~\ref{chapter:simple-invariants} are needed to show that the context
bounds imply the expected bounds.

\subsection{Extending canonicalization to two's complement signed integer arithmetic}

In some widely-used C compilers, signed arithmetic implemented
as two's complement arithmetic is available under a compiler flag. In
this case, the expected arithmetic properties hold, which enables more
expressions to be canonicalized to the same form.

\section{Declarations}
\label{section:checking-declarations}

Declarations also need to be checked for consistency with their bounds
declarations. If the declaration is within a bundled block, the checking
is deferred to the end of the bundled block.

C distinguishes between declarations and definitions of variables. A
declaration declares the type and storage class for a variable. It may
or may not cause storage to be allocated for the variable. A definition
is a declaration of a variable that causes storage to be allocated for
the variable as well. Definitions may have initializers that initialize
the storage for the variable.

We first describe checking definitions, which is similar to checking
assignments. For a declaration, we assume that there is an ordered list of
\arrayptr\ variables and their optional initializers, and the
list of bounds declarations in the where clause for the declaration. The
list is ordered by the order of variable declarations.

First, the current context is computed before the declaration. Then, for
each variable \var{v} in the list,

\begin{itemize}
\item
  If \var{v} has an initializer, the current context is updated by
  traversing the assignment expressions in the initializer using the
  analysis from Section~\ref{section:checking-complex-expressions}.
  The bounds for each individual assignment
  expression are recorded as well. Note that if \var{v} is a static
  variable, the assignment expressions must actually be constant
  expressions, so the context will not change.
\item
  If \var{v} has an \arrayptr\ type or an incomplete array
  type, the context is updated to record the new bounds for \var{v}:

  \begin{itemize}
  \item
    If \var{v} has no initializer, then

    \begin{itemize}
    \item
      If \var{v} is a static variable, then \var{v} will be
      initialized to 0. The context is updated to map \var{v} to
      \boundsany.
    \item
      If \var{v} is an automatic variable then \var{v} will have an
      indeterminate value. The context is updated to map v to
      \boundsunknown.
    \end{itemize}
  \item
    If \var{v} has an initializer, the initializer must have the form
    \var{e} or \lstinline|{| \var{e} \lstinline|}|. In both cases,

    \begin{itemize}
    \item
      If a temporary variable has been introduced for the value
      of \var{e} and the temporary variable appears in the bounds for
      \var{e}, \var{v} is substituted for it.
    \item
      The context is updated to map v to the updated bounds.
    \end{itemize}
  \end{itemize}
\end{itemize}

The current context is then checked against the bounds declarations that
must be true after the declaration using the analysis in
Section~\ref{section:checking-full-expressions}

Declarations that are not definitions are not checked, other than to
verify that all the declarations of a variable in a translation unit
have the same bounds declaration (or lack of a bounds declarations) for
the variable.

\section{Bundled declarations and statements}
\label{section:checking-bundled}

To check bundled declarations and statements, the current context is
determined before the bundled block. The current context is then updated
for each expression statement and declaration following the rules for
updating contexts in Sections~\ref{section:checking-full-expressions} and
\ref{section:checking-declarations}. The analysis of
Section~\ref{section:extent-definition}
is used to determine the expected bounds expression for each variable at
the end of the bundled block. The current context is checked against the
bounds declarations that must be true at the end of the block using the
analysis in Section~\ref{section:checking-full-expressions}

When an expression with \arrayptr\ type is dereferenced within
an expression statement in a bundled block, the current context before
the statement is used to determine the bounds for the expression. This
may cause an expression to have a different bounds than it normally
would have based on bounds declarations.

For example, suppose a pointer assignment is introduced into the middle
of the earlier example. The pointer assignment is highlighted in blue.
The bounds for \lstinline|parr| at that point in the program based on the
current context will be \lstinline|bounds(parr, parr + size)|.

\begin{lstlisting}[escapechar=\|]
int arr[DEFAULT_SIZE];
array_ptr<int> parr : count(len) = arr;
int plen = DEFAULT_SIZE;

f(int size) {
  if (size > DEFAULT_SIZE) {
    bundle {
      parr = malloc(sizeof(int) * size);
      |\sethlcolor{lightblue}\hl{*parr = 314;}|
      plen = size;
    }
  }
}
\end{lstlisting}

If the code were slightly rearranged, there would be a compile-time
error. The assignment to \code{plen} invalidates the bounds for
\code{parr} in the context at the point of the assignment.

\begin{lstlisting}[escapechar=\|]
f(int size) {
  if (size > DEFAULT_SIZE) {
    bundle {
      plen = size;
      |\sethlcolor{lightblue}\hl{*parr = 314;}| // error: parr has bounds of none.
      parr = malloc(sizeof(int) * size);
    }
  }
}
\end{lstlisting}

A function call within a bundled block require special treatment: the
bounds declarations for variables with static storage must be valid
before the call. The called function is assuming that the declared
bounds are valid. This means that the context before the function call
must imply that bounds declarations for variables in scope that have
static storage are valid.

\section{Function call arguments}
\label{section:checking-function-call-arguments}

Function call arguments also need to be checked for consistency with
expected bounds declarations. This is similar to checking of expression
statements with where clauses. For each call f(e\textsubscript{1}
\ldots{} e\textsubscript{n}) to a function f(x\textsubscript{1} \ldots{}
x\textsubscript{n}) that has bounds declarations for one or more
parameters,

\begin{itemize}
\item
  A statement of the form

  x\textsubscript{1} = e\textsubscript{1} \code{,} x\textsubscript{2} =
  e\textsubscript{2} \code{,} \ldots{}. x\textsubscript{n} =
  e\textsubscript{n} where \var{conditions}\code{;}

  is constructed, where \var{conditions} contains all the bounds
  declarations on parameters. Parameters are renamed if necessary so
  that they have different names from variables in scope at the function
  call.
\item
  The context for the function call is constructed. The statement is
  checked in that context using the rules in
  Section~\ref{section:checking-full-expressions}
\item
  A subtle point is that the order of evaluation for argument
  expressions in C is not defined (Section~\ref{section:avoiding-undefinedness}
  discusses order of
  evaluation issues in depth). A check is done also that the values of
  argument expressions used in checking the bounds declaration do not
  depend on the order of evaluation of arguments:

  \begin{itemize}
  \item
    The set of parameters that occur in bounds declarations for
    parameters is computed.
  \item
    Any argument expression corresponding to a parameter in this set
    cannot read a variable that is assigned to by another argument
    expression. If one does, the function call is rejected as not
    checking.
  \end{itemize}
\end{itemize}

 \section{Return statements}
 \label{section:checking-return-statements}

A return statement has the form \code{return} \var{e}, where \var{e}
is optional. If the special
variable \keyword{return\_value} occurs in the return bounds
for the function
\begin{itemize}
\item a new temporary is created and substituted for
\keyword{return\_value} in the return bounds.
\item  It is recorded that the new temporary and the result
of evaluating \var{e} are equal.
\end{itemize}
The bounds for \var{e} are computed.   It is then checked that
the bounds for \var{e} imply the (possibly updated) return
bounds, using  the rules in
Section~\ref{section:checking-full-expressions}

Note that if the bounds of \var{e} involve a temporary,
the temporary does not occur in the (possibly updated) return bounds,
and no sets of equivalent expressions have been recorded involving the temporary,
the bounds of \var{e} cannot imply the return bounds are
valid.  There will be no connection between the temporary
and values used in the return bounds.

\section{Other statements}

There are a variety of other statements in C. These statements are built
from zero or more expressions, statements, and declarations:

\begin{itemize}
\item
  Labeled statements of the form \code{case}
  \var{constant-expression} \code{:} \var{statement},
  \code{default :} \var{statement}, and \var{identifier} :
  \var{statement}.
\item
  Selection statements of the form \code{if (}\var{expression}\code{)}
  \var{statement} \code{else}
  \var{statement} and \code{switch (}\var{expression}\code{)}
  \var{statement}.
\item
  Iteration statements such as \code{while (}\var{expression}\code{)}
  \var{statement} and \code{for (}\var{declaration\textsubscript{opt}}
  \var{expression\textsubscript{opt}}\code{;} \var{expression\textsubscript{opt}} \code{;}
   \var{expression\textsubscript{opt}}\code{)} \var{statement}.
\item
  Jump statements of the from \code{goto} \var{identifier},
  \code{continue}, and \code{break}.
\item
  Compound statements of the form \lstinline|{ ... }| where \lstinline|...|
  are zero or more declarations or statements.
\end{itemize}

The nested statements and declarations can be checked individually.

For the full expressions used in the statements, the context is determined
before the evaluation of the full expression. No way is provided for a
full expression occurring in a statement to have new bounds declared
for any variables in it. This means that the bounds declarations in the
context will be expected to be true after the evaluation of the full expression too.

The rules in Section~\ref{section:checking-complex-expressions}
are used to determine the updated context after evaluation of the
expression. The rules in Section~\ref{section:checking-full-expressions}
are used to check that the updated
context implies the expected bounds declarations.