Too much assumed about temporary or unassigned variables #1619
Labels
logic
An inconsistency in Dafny's logic (e.g. in the Boogie prelude)
part: verifier
Translation from Dafny to Boogie (translator)
The following program verifies and compiles, but crashes at run time:
Diagnosis
The problem has to do with
where
-clause assumptions that are generated for variables. Here's some context.The verifier translates a local variable
x
of a typeX
into a similar local variable in Boogie. IfBX
is the Boogie type that includes all Dafny-X
values, then the Boogie declaration looks something like this:The Boogie type
BX
may be bigger than the Dafny typeX
, so the verifier adds the more precise information using assumptions. Boogie'swhere
clauses give a convenient place to hang such an assumption. So, in the typical case, the Boogie declaration ofx
looks something like:This is fine as long as long as
X
denotes a nonempty type.If
X
denotes a possibly empty type, then Dafny puts into effect a definite-assignment rule. This rule, which is enforced by the verifier, checks that any use of the variablex
is preceded by an assignment tox
. For the sake of soundness, the verifier must arrange that$Is(x, X)
does not get assumed until afterx
has been assigned. This is done by emitting a second Boogie variable, nameddefass$x
. This variable is set totrue
whenx
is assigned. So, in the case thatX
denotes a possibly empty type, the declarations generated are:So far, all good. The Dafny verifier incorporates this design. But there are two places where an incorrect
where
clause is generated.One place is for temporary variables. In particular, for a Dafny call
x := MyMethod();
, the verifier generatesand for a simultaneous assignment
x, y := E, F;
, the verifier generatesThe problem is that the temporary variable
rhs$0
(and similar forrhs$1
) is currently declared with awhere
clause:A temporary variable does not need a
where
clause. (And even if it did have one, it would need to replicate the definite-assignment mechanism. But it doesn't need awhere
clause at all.) So, this is one problem that should be fixed.The other place where an incorrect
where
clause is generated is when the Dafny program declares and immediately assigns a variable, likevar x := E;
. In this case, every Dafny use of the variablex
will be afterx
has been assigned, so there seems to be no reason to bring in thedefass$x
mechanism. Wrong! While the Dafny part of the argument I made is correct, the Boogiewhere
clause will be available even before the Dafny initializationx := E;
has happened. The verifier gets this wrong. It should apply this optimization only for nonempty types.PS. If the Dafny statement
var cand: W := GimmieOne(s);
in the program above is broken up into a declarationvar cand: W;
and an assignmentcand := GimmieOne(s);
, then one runs into a bug in the compiler. That bug has already been reported in #1553.The text was updated successfully, but these errors were encountered: