1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
|
\htmlhr
\chapterAndLabel{Aliasing Checker}{aliasing-checker}
The Aliasing Checker identifies expressions that definitely have no
aliases.
Two expressions are aliased when they have the same non-primitive value;
that is, they are references to the identical Java object
in the heap. Another way of saying this is that two expressions,
$\mathit{exprA}$ and $\mathit{exprB}$, are aliases of each other when
$\mathit{exprA} \<==> \mathit{exprB}$ at the same program point.
Assigning to a variable or field typically creates an alias. For example,
after the statement \<a = b;>, the variables \<a> and \<b> are aliased.
Knowing that an expression is not aliased permits more accurate reasoning
about how side effects modify the expression's value.
To run the Aliasing Checker, supply the
\code{-processor org.checkerframework.common.aliasing.AliasingChecker}
command-line option to javac.
However, a user rarely runs the Aliasing Checker directly.
This type system is mainly intended to be used together with other type systems.
For example, the SPARTA information flow type-checker
(Section~\ref{sparta-checker}) uses the Aliasing Checker to improve its
type refinement --- if an expression has no aliases, a more refined type
can often be inferred, otherwise the type-checker makes conservative
assumptions.
\sectionAndLabel{Aliasing annotations}{aliasing-annotations}
\begin{figure}
\includeimage{aliasing}{2cm}
\caption{Type hierarchy for the Aliasing type system.
These qualifiers are applicable to any reference (non-primitive) type.}
\label{fig-aliasing-hierarchy}
\end{figure}
There are two possible types for an expression:
\begin{description}
\item[\refqualclass{common/aliasing/qual}{MaybeAliased}]
is the type of an expression that might have an alias.
This is the default, so every unannotated type is
\code{@MaybeAliased}. (This includes the type of \code{null}.)
\item[\refqualclass{common/aliasing/qual}{Unique}]
is the type of an expression that has no aliases.
The \code{@Unique} annotation is only allowed at local variables, method
parameters, constructor results, and method returns.
A constructor's result should be annotated with \code{@Unique} only if the
constructor's body does not creates an alias to the constructed object.
\end{description}
There are also two annotations, which are currently trusted instead of verified,
that can be used on formal parameters (including
the receiver parameter, \<this>):
\begin{description}
\item[\refqualclass{common/aliasing/qual}{NonLeaked}]
identifies a formal parameter that is not leaked nor
returned by the method body.
For example, the formal parameter of the String copy constructor,
\code{String(String s)}, is \code{@NonLeaked} because the body of the method
only makes a copy of the parameter.
\item[\refqualclass{common/aliasing/qual}{LeakedToResult}]
is used when the parameter may be returned, but it is not
otherwise leaked.
For example, the receiver parameter of \code{StringBuffer.append(StringBuffer
this, String s)} is
\code{@LeakedToResult}, because the method returns the updated receiver.
\end{description}
\sectionAndLabel{Leaking contexts}{aliasing-leaking-contexts}
This section lists the expressions that create aliases. These are also
called ``leaking contexts''.
\begin{description}
\item[Assignments]
After an assignment, the left-hand side and the right-hand side are
typically aliased. (The only counterexample is when the right-hand side is
a fresh expression; see Section~\ref{aliasing-refinement}.)
\begin{Verbatim}
@Unique Object u = ...;
Object o = u; // (not.unique) type-checking error!
\end{Verbatim}
If this example type-checked, then \<u> and \<o> would be aliased.
For this example to type-check, either the \<@Unique> annotation on the
type of \<u>, or the \<o = u;> assignment, must be removed.
\item[Method calls and returns (pseudo-assignments)]
Passing an argument to a method is a ``pseudo-assignment'' because it effectively
assigns the argument to the formal parameter. Return statements are also
pseudo-assignments.
As with assignments, the left-hand side and right-hand side of
pseudo-assignments are typically aliased.
Here is an example for argument-passing:
\begin{Verbatim}
void mightDoAnything(Object o) { ... }
@Unique Object u = ...;
mightDoAnything(u); // type-checking error, because the callee may create an alias of the passed argument
\end{Verbatim}
Passing a non-aliased
reference to a method does not necessarily create an alias.
However, the body of the method might create an alias or leak the
reference. Thus, the Aliasing Checker always treats a method call as
creating aliases for each argument unless the corresponding formal
parameter is marked as
@\refqualclass{common/aliasing/qual}{NonLeaked} or
@\refqualclass{common/aliasing/qual}{LeakedToResult}.
Here is an example for a return statement:
\begin{Verbatim}
Object id(@Unique Object p) {
return p; // (not.unique) type-checking error!
}
\end{Verbatim}
If this code type-checked, then it would be possible for clients to write
code like this:
\begin{Verbatim}
@Unique Object u = ...;
Object o = id(u);
\end{Verbatim}
\noindent
after which there is an alias to \<u> even though it is declared as \<@Unique>.
However, it is permitted to write
\begin{Verbatim}
Object id(@LeakedToResult Object p) {
return p;
}
\end{Verbatim}
\noindent
after which the following code type-checks:
\begin{Verbatim}
@Unique Object u = ...;
id(u); // method call result is not used
Object o1 = ...;
Object o2 = id(o1); // argument is not @Unique
\end{Verbatim}
\item[Throws]
A thrown exception can be captured by a catch block, which creates an
alias of the thrown exception.
\begin{Verbatim}
void aliasInCatchBlock() {
@Unique Exception uex = new Exception();
try {
throw uex; // (not.unique) type-checking error!
} catch (Exception ex) {
// uex and ex refer to the same object here.
}
}
\end{Verbatim}
\item[Array initializers]
Array initializers assign the elements in the initializers to corresponding
indexes in the array, therefore expressions in an array initializer are leaked.
\begin{Verbatim}
void aliasInArrayInitializer() {
@Unique Object o = new Object();
Object[] ar = new Object[] { o }; // (not.unique) type-checking error!
// The expressions o and ar[0] are now aliased.
}
\end{Verbatim}
%Remember to add enhanced for statement if support to type variables is added.
\end{description}
\sectionAndLabel{Restrictions on where \<@Unique> may be written}{aliasing-unique-restrictions}
The \<@Unique> qualifier may not be written on locations such as fields,
array elements, and type parameters.
As an example of why \<@Unique> may not be written on a field's type,
consider the following code:
\begin{Verbatim}
class MyClass {
@Unique Object field;
void makesAlias() {
MyClass myClass2 = this;
// this.field is now an alias of myClass2.field
}
}
\end{Verbatim}
That code must not type-check, because \<field> is declared as \<@Unique>
but has an alias. The Aliasing Checker solves the problem by forbidding
the \<@Unique> qualifier on subcomponents of a structure, such as fields.
Other solutions might be possible; they would be more complicated but would
permit more code to type-check.
\<@Unique> may not be written on a type parameter for similar reasons.
The assignment
\begin{Verbatim}
List<@Unique Object> l1 = ...;
List<@Unique Object> l2 = l1;
\end{Verbatim}
\noindent
must be forbidden because it would alias \<l1.get(0)> with \<l2.get(0)>
even though both have type \<@Unique>. The Aliasing Checker forbids this
code by rejecting the type \code{List<@Unique Object>}.
\sectionAndLabel{Aliasing type refinement}{aliasing-refinement}
Type refinement enables a type checker to treat an expression as a subtype
of its declared type. For example, even if you declare a local variable as
\<@MaybeAliased> (or don't write anything, since \<@MaybeAliased> is the
default), sometimes the Aliasing Checker can determine that it is actually
\<@Unique>.
% This prevents the type checker from issuing false positive warnings.
For more details, see Section~\ref{type-refinement}.
The Aliasing Checker treats type refinement in the usual way,
except that at (pseudo-)assignments
the right-hand-side (RHS) may lose its type refinement, before the
left-hand-side (LHS) is type-refined.
The RHS always loses its type refinement (it is widened to
\code{@MaybeAliased}, and its declared type must have been
\code{@MaybeAliased}) except in the following cases:
\begin{itemize}
\item
The RHS is a fresh expression --- an expression that returns a different value
each time it is evaluated. In practice, this is only method/constructor calls
with \code{@Unique} return type. A variable/field is not fresh because it can
return the same value when evaluated twice.
\item
The LHS is a \code{@NonLeaked} formal parameter and the RHS is an argument in a
method call or constructor invocation.
\item
The LHS is a \code{@LeakedToResult} formal parameter, the RHS is an argument in
a method call or constructor invocation, and the method's return value is
discarded --- that is, the method call or constructor invocation is written
syntactically as a statement rather than as a part of a larger expression or
statement.
\end{itemize}
%(Notice that the last two rules above are restricted to pseudo-assignments.)
A consequence of the above rules is that most method calls are treated conservatively.
If a variable with declared type \code{@MaybeAliased} has been refined
to \code{@Unique} and is used as an argument of a method call, it usually loses its
\code{@Unique} refined type.
Figure~\ref{fig-aliasing-refinement-example} gives an example of the Aliasing Checker's
type refinement rules.
\begin{figure}
%BEGIN LATEX
\begin{smaller}
%END LATEX
\begin{Verbatim}
// Annotations on the StringBuffer class, used in the examples below.
// class StringBuffer {
// @Unique StringBuffer();
// StringBuffer append(@LeakedToResult StringBuffer this, @NonLeaked String s);
// }
void foo() {
StringBuffer sb = new StringBuffer(); // sb is refined to @Unique.
StringBuffer sb2 = sb; // sb loses its refinement.
// Both sb and sb2 have aliases and because of that have type @MaybeAliased.
}
void bar() {
StringBuffer sb = new StringBuffer(); // sb is refined to @Unique.
sb.append("someString");
// sb stays @Unique, as no aliases are created.
StringBuffer sb2 = sb.append("someString");
// sb is leaked and becomes @MaybeAliased.
// Both sb and sb2 have aliases and because of that have type @MaybeAliased.
}
\end{Verbatim}
%BEGIN LATEX
\end{smaller}
%END LATEX
\caption{Example of the Aliasing Checker's type refinement rules.}
\label{fig-aliasing-refinement-example}
\end{figure}
%% LocalWords: MaybeAliased NonLeaked LeakedToResult l1 l2 RHS LHS
%% LocalWords: subcomponents
|