2

I've got a procedure within a SPARK module that calls the standard Ada-Text_IO.Put_Line.

During proving I get the following warning warning: no Global contract available for "Put_Line".

I do already know how to add the respective data dependency contract to procedures and functions written by myself but how do I add them to a procedures / functions written by others where I can't edit the source files?

I looked through sections 5.2 and 7.4 of the Adacore SPARK 2014 user's guide but didn't found an example with a solution to my problem.

Simon
  • 594
  • 1
  • 6
  • 13

3 Answers3

3

This means that the analyzer cannot "see" whether global variables might be affected when this function is called. It therefore assumes this call is not modifying anything (otherwise all other proofs could be refuted immediately). This is likely a valid assumption for your specific example, but it might not be valid on an embedded system, where a custom implementation of Put_Line might do anything.

There are two ways to convey the missing information:

  1. verifier can examine the source code of the function. Then it can try to generate global contracts itself.
  2. global contracts are specified explicitly, see RM 6.1.4 (http://docs.adacore.com/spark2014-docs/html/lrm/subprograms.html#global-aspects)

In this case, the procedure you are calling is part of the run-time system (RTS), and therefore the source is not visible, and you probably cannot/should not change it.

What to do in practice?

Suppressing warnings is almost never a good idea, especially not when you are working on something safety-critical. Usually the code has to be changed until the warning goes away, or some justification process has to start.

If you are serious about the analysis results, I recommend to not use such subprograms. If you really need output there, either write your own procedure that replaces the RTS subprogram, or ensure that the subprogram really has no side effects. This is further backed up by what Frédéric has linked: Even if the callee has no side effects, you don't know whether it raises an exception for specific inputs (e.g., very long strings).

If you are not so serious about the results, then you can consider this specific one as a warning that you could live with.

Martin B
  • 111
  • 1
  • 1
    Since I used Put_Line for debugging only, I just removed the line and am happy with that. – Simon Jan 26 '18 at 21:42
2

Wrapper packages for use in development of SPARK applications may be found here: https://github.com/joakim-strandberg/aida_2012

1

I think you just can't add Spark contracts on code you don't own, especially code from the Ada standard.

About Text_Io, I found something that may be valuable to you in the reference manual.

EDIT

Another solution compared to what Martin said, according to "Building high integrity applications with Spark" book, is to create a wrapper package.

As Spark requires you to deal with Spark packages but allows you to depend on a Spark spec with an Ada body, the solution is to build a Spark package wrapping your Ada.Text_io calls.

It might be tedious as you will have to wrap possible exceptions, possibly define specific types and so on but this way, you'll be able to discharge VCs on your full Spark package.

Frédéric Praca
  • 1,620
  • 15
  • 29
  • Thank you very much for the reference to the reference manual. `Put_Line` is neither mentioned positively nor negatively which means that I should be able to use the function. How do I tell SPARK to suppress the warning then? Would a wrapper procedure be a viable alternative? – Simon Jan 24 '18 at 10:44
  • Can you use e.g. `pragma Warnings (Off, "*Put_Line*");`? (not sure about the wildcards there) – Simon Wright Jan 24 '18 at 19:53
  • @SimonWright: pragma Warnings (Off ...); works as you suggest. – Joakim Strandberg Feb 02 '18 at 09:29