An ACSL contract can be structured into a list of behaviors, which describe the various cases in which the function might be called (see ACSL manual for more information). They are introduced like this:
/*@
behavior A:
assumes some_condition;
requires ...
assigns ...
ensures ...
behavior B: ...
*/
If the assumes
clause is true when the function is called, the behavior is active, and the other clauses in the behavior must be satisfied.
The so-called Default behavior encompasses the clauses that do not belong to an explicit behavior: it is a bit like if you had written your contract as such:
/*@
behavior Default:
assumes \true;
requires valid_read_string(s);
assigns \result \from indirect:s[0..];
ensures \result == strlen(s);
*/
The validity status of a behavior (including the default one) is simply the consolidation of the statuses of its components (i.e. it will be valid if and only if all components are validated). It is computed by the kernel from the statuses put on each individual components by the plug-ins (here, WP).
Now, where does the "Unknown" come from, since it looks like all annotations have been proved? In fact, this is not the case: the way you have written your assigns clause, assigns \result \from indirect:s[0..];
implies that there are two things to prove: first that the function does not modify the global state of the program (this is validated by WP), and second that the result only depend on the content of s (this is not done, and in fact no plug-in is currently capable of doing it). This is this second property, often referred to as a from
clause, that is causing the kernel to consider that the Default behavior is not fully proved. Unfortunately, it appears that this from
clause is not even present in Report's output, which make things even more confusing.
UPDATE As suggested by an esteemed former colleague, I've dug a bit into the lack of report for the from
clause: by default untried properties are not displayed by -report
, you have to explicitly set -report-untried
(which then gives you all the preconditions of the function of the standard library that you don't call, and the from
of get_len
as expected).