4.4. SEGUIMIENTO Y CONTROL DEL PLAN DE GESTIÓN INTEGRAL DE
4.4.8. DISPOSICIÓN FINAL
The current ESC/Java does not check that the body of a routine actually obeys the constraint expressed by the routine's modifies pragmas. This lack of checking is one of several potential sources of missed warnings
(unsoundness). The potential for missed warnings is mitigated somewhat by a fact that may have seemed surprising when we mentioned it in the previous section (2.3.2): If a particular field (either a static field or an instance variable) is not specified as a target field (section 2.3.1.0) of a routine, then occurrences of that field within arguments to \old in the routine's postconditions are taken to refer to post-state values.
Consider, for example a class with an integer field f and a method incf declared as follows, with no modifies
pragma:
//@ ensures f == \old(f) + 1; void incf() {
this.f++; }
Since f is not specified as a modification target of incf, ESC/Java will interpret both occurrences of f in the
ensures pragma as referring to the post-state value of this.f. Consequently ESC/Java will be unable to show
that the method establishes the specified postcondition, and will issue a warning to that effect.
While this warning may seem surprising, the result of interpreting the second occurrence of f as the pre-state
value of this.f would be even worse. Under the latter interpretation ESC/Java would issue no warnings about
the body of incf, but would assume after a call x.incf() both (1) that x.f had been incremented in
accordance the postcondition), and (2) that x.f was left unchanged in accordance with the (unchecked) empty
set of modification targets. Since these assumptions are mutually contradictory, the result would be equivalent to assuming false, and ESC/Java would silently omit all checking after the call.
As an additional guard against omission of modifies pragmas, ESC/Java issues a caution message for any
occurrence of \old(X) in a postcondition of a method m unless (1) the expression X mentions some target field
of m, or (2) the expression X includes an array access and m has some modification target of the form A[I] or A[*].
Of course, the interactions of modifies and \old described above do not entirely make up for the fact that the
current ESC/Java does no checking of modifies pragmas. A method declaration like
//@ modifies someOtherObject.f; //instead of this.f
//@ ensures f == \old(f) + 1; void incf() {
this.f++; }
can still effectively disable checking of code following calls to incf. 2.3.4 exsures pragma
An exsures pragma is a routine modifier pragma. It has the form exsures (T t) E ;
opt
or
exsures (T) E ; opt
where T is a subtype of java.lang.Throwable, t (if included) is a an identifier, and E is a boolean specification
expression. The identifier t (if included) is in scope in E, where it has type T. The pragma makes E an
exceptional postcondition of the routine the pragma modifies. That is, it specifies that E holds whenever the
routine completes abruptly by throwing an exception t whose type is a subtype of T.
When checking the body of the routine, ESC/Java checks that E holds whenever the routine completes abruptly
by throwing an exception t whose type is a subtype of T. When checking code that calls the routine, ESC/Java
assumes that the E holds just after the call if the call completes abruptly with an exception whose type is a subtype
of T.
Like normal postconditions, exceptional postconditions of synchronized methods apply to the state after the
release of the lock.
The identifier t may not be the same as any formal parameter of the routine, and quantified expressions (see
sections 3.2.10 and 3.2.11) within E may not use t as a bound variable name.
The expression E can include uses of \fresh and \old, which have the same semantics as in an ensures
pragma. However, E cannot mention \result, since an abruptly-terminating routine invocation returns no
result. Similarly E cannot mention this if the exsures pragma modifies a constructor, since we take the view
that the object being constructed should be discarded. (This view is potentially unsound; see section C.0.8.) A single routine declaration may be modified with any number of exsures pragmas. ESC/Java checks that the
body obeys each exsures pragma and assumes that calls obey each exsures pragma. For example, if a
routine is modified by the pragmas
exsures (T1 t) E1; exsures (T2 t) E2;
where T2 is a subtype of T1, then ESC/Java checks (if checking the body of the routine) or assumes (if checking
a caller) that E1 holds whenever the routine completes abruptly by throwing an exception that is an instance of T1, and that both E1 and E2 hold whenever the routine completes abruptly by throwing an exception that is an
instance of T2.
A method declaration that overrides another method declaration cannot be modified with an exsures pragma,
but inherits the exceptional postconditions of the overridden method. (See also the also_exsures pragma
described in section 2.3.6.) 2.3.5 also_ensures pragma
An also_ensures pragma is a routine modifier pragma. It has the form
also_ensures E ;
opt
where E is a boolean specification expression. An also_ensures pragma has the same semantics as an ensures pragma, but may appear as a modifier only of a method declaration that overrides another method
declaration (while overriding method declarations are forbidden to have ensures pragmas).