How do you declare 'assigns' clause with multidimensional arrays in frama-c? - pointers

I have the following variables:
int** send_count;
message_struct*** send_queue;
And I have a function I want to declare a contract for
message_record_struct postSend(int destination, double* buf);
How do I declare a contract which allows assignment to the elements of send_count and send_queue?
I'm concerned the following approach only allows assignment to the element at the address of pointer to the array:
# assigns send_count
And the following approach throws an error given the axiomatic theory { logic integer NP; } in an earlier portion of the code):
# assigns *(send_count+(0..NP-1));
# assigns \forall integer i; 0<=i<NP ==>
*(send_count[i]+(0..NP-1));
$ frama-c -wp -wp-prover "why3ide" assign_example.c
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i (no preprocessing)
[kernel] Parsing assign_example.c (with preprocessing)
assign_example.c:62:[kernel] user error: syntax error (expression expected but predicate found) in annotation.
[kernel] user error: stopping on file "assign_example.c" that has errors. Add '-kernel-msg-key pp' for preprocessing command.
[kernel] Frama-C aborted: invalid user input.

The syntax you are looking for is probably
/*# assigns *(send_count+(0..NP-1));
assigns *(send_count[0..NP-1]+(0..NP-1));
ACSL ranges [a..b] have been introduced to keep assigns clauses quantifiers-free, and should be used as much as possible.

Related

Ada complaining that I've added a volatile object in a function call to generic type when not volatile

So I've got the following declaration:
record
String1 : String (1 .. 64);
String2 : String (1 .. 64);
Timestamp : Time;
Int1 : Long_Long_Integer;
String3 : Unbounded_String;
end record;
And it's used in
package My_Vectors is new Vectors (Index_Type => Positive, Element_Type => Object);
which yields the compilation error:
volatile object cannot act as actual in a call (SPARK RM 7.1.3(10))
Now, Clock is volatile which is used. However I've removed the call to Clock and I still get the same result.
Also, I've tried replacing the Object type with a type of Integer and I don't have any complaints from the Ada compiler. Could someone explain this as I can't see how this is putting a volatile object into an actual anywhere please.
Just tried using the following record and I get the same result:
type My_Record is
record
A: Integer;
B: Integer;
C: String(1 .. 64);
end record;
The standard Ada containers are not supported in SPARK (see SPARK RM 14.8).
Use the SPARK compatible container Ada.Containers.Formal_Vectors instead (see also here and here).
Regarding the compiler error: the current implementation of Ada.Containers.Vector uses atomic operations to improve performance (see here and here). These atomic operations operate (in this case) on variables of type System.Atomic_Counters.Atomic_Unsigned (see here). This type is declared as Atomic and therefore volatile (see RM 8(3)).

How to convert OCaml signal to POSIX signal or string?

I run a subprocess from an OCaml program and check its termination status. If it exited normally (WEXITED int), I get the expected return code (0 usually indicating success).
However, if it was terminated by a signal (WSIGNALED int), I don't get the proper POSIX signal number. Instead, I get some (negative) OCaml specific signal number.
How do I convert this nonstandard signal number to a proper POSIX signal number, for proper error reports? Alternatively, how do I convert this number to a string?
(I'm aware that there are tons of named integer values like Sys.sigabrt, but do I really have to write that large match statement myself? Moreover, I don't get why they didn't use a proper variant type in the first place, given that those signal numbers are OCaml specific anyway.)
There is a function in the OCaml runtime that does this conversion (naturally). It is not kosher to call this function, but if you don't mind writing code that can break in future releases of OCaml (and other possibly bad outcomes), here is code that works for me:
A wrapper for the OCaml runtime function:
$ cat wrap.c
#include <caml/mlvalues.h>
extern int caml_convert_signal_number(int);
value oc_sig_to_host_sig(value ocsignum)
{
/* Convert a signal number from OCaml to host system.
*/
return Val_int(caml_convert_signal_number(Int_val(ocsignum)));
}
A test program.
$ cat m.ml
external convert : int -> int = "oc_sig_to_host_sig"
let main () =
Printf.printf "converted %d -> %d\n" Sys.sigint (convert Sys.sigint)
let () = main ()
Compile the program and try it out:
$ ocamlopt -o m -I $(ocamlopt -where) wrap.c m.ml
$ ./m
converted -6 -> 2
All in all, it might be better just to write some code that compares against the different signals defined in the Sys module and translates them to strings.

Where is the implementation of the function `_PyIO_str_readline` on the C Python implementation?

On the question, How is file implemented? I learned how open() method is implemented, but I cannot find where the _PyIO_str_readline function used on its implemented is defined.
https://docs.python.org/3/c-api/object.html
https://github.com/python/cpython/search?q=_PyIO_str_readline
Your problem is that you think, _PyIO_str_readline is a function, but actually it is just a global variable (of type PyObject *), which is declared here:
extern PyObject *_PyIO_str_readline;
and defined here:
PyObject *_PyIO_str_readline = NULL;
to be NULL, but as name suggest could by any string-object (i.e. unicode in Python3 or bytes in Python2).
_PyIO_str_readline is a kind of a cache (often referenced as "interned string" in CPython - see PyUnicode_InternFromString), so every time PyObject_CallMethodObjArgs is called with "readline" as method-name, the corresponding object must not be constructed anew.
_PyIO_str_readline is initialized in PyInit__io to its actual value, using macro ADD_INTERNED:
/* Interned strings */
#define ADD_INTERNED(name) \
if (!_PyIO_str_ ## name && \
!(_PyIO_str_ ## name = PyUnicode_InternFromString(# name))) \
goto fail;
...
ADD_INTERNED(readline)
..
i.e. _PyIO_str_readline is an unicode-object with value readline. Which readline-method is actually used, is resolved during the run time and depends on what self actually is.

Ada.Containers.Vectors not working with GNAT GPL 2017

I am trying to compile this code:
with Ada.Containers.Vectors;
procedure Test is
type My_Type is range -1 .. Integer'Last;
package My_Vectors is new Ada.Containers.Vectors (Positive, My_Type);
Vector : My_Vectors.Vector;
begin
Vector.Append (-1);
end Test;
gnatmake test.adb gives this output:
gcc -c test.adb
a-convec.adb:1553:33: missing operand
gnatmake: "test.adb" compilation error
The error message leads to this procedure in the stdlib's implementation:
procedure Insert
(Container : in out Vector;
Before : Extended_Index;
Count : Count_Type := 1)
is
New_Item : Element_Type := <>; -- << here
pragma Warnings (Off, New_Item);
begin
Insert (Container, Before, New_Item, Count);
end Insert;
It looks fine. I don't understand the error message, what's wrong here? Is it a bug in the stdlib?
Looks like this file has been tampered with…
Summarizing the evidence,
Multiple comments report no problem with GNAT versions going back as far as 4.9.1.
The initialization marked << here is a compile-time error, as the compound delimiter <>, named box, is not valid in an expression used in assignment.
Based on How gnatmake Works, a-convec.adb would only be recompiled if it were modified after the corresponding .ali file.
Going forward, you might
Check the modification dates of a-convec.adb and a-convec.ali, found in the adainclude and adalib directories, respectively.
Reinstall the compiler.
Notify upstream maintainers if warranted.

Frama-C generates confusing assertions about pointer comparison

I'm getting assertions that don't make sense to me.
Code:
struct s {
int pred;
};
/*# assigns \result \from \nothing;
ensures \valid(\result);
*/
struct s *get(void);
int main(void)
{
return !get()->pred;
}
Frama-C output:
$ frama-c -val frama-ptr.c
[...]
frama-ptr.c:12:[kernel] warning: pointer comparison.
assert \pointer_comparable((void *)0, (void *)tmp->pred);
(tmp from get())
Am I doing something wrong or is it a bug in Frama-C?
This is not really a bug, although this behavior is not really satisfactory either. I recommend that you observe the analysis in the GUI (frama-c-gui -val frama-ptr.c), in particular the value of tmp->pred at line 12 in the Values tab.
Value before:
∈
{{ garbled mix of &{alloced_return_get}
(origin: Library function {c/ptrcmp.c:12}) }}
This is a very imprecise value, that has been generated because the return value of function get is a pointer. The Eva plugin generates a dummy variable (alloced_return_get), and fills it with dummy contents (garbled mix of &{alloced_return_get}). Even though the field pred is an integer, the analyzer assumes that (imprecise) pointers can also be present. This is why an alarm for pointer comparison is emitted.
There are at least two ways to avoid this:
use option -val-warn-undefined-pointer-comparison pointer, so that pointer comparison alarms are emitted only on comparisons involving lvalues with pointer type. The contents of the field pred will remain imprecise, though.
add a proper body to function get, possibly written using malloc, so that the field pred receives a more accurate value.
On a more general note, the Eva/Value plugin requires precise specifications for functions without a body; see section 7.2 of the manual. For functions that return pointers, you won't be able to write satisfactory specifications: you need to write allocates clauses, and those are currently not handled by Eva/Value. Thus, I suggest that you write a body for get.

Resources