没有全球合同可用于程序/功能

时间:2018-01-23 22:47:22

标签: ada gnat spark-ada

我在SPARK模块中有一个调用标准Ada-Text_IO.Put_Line的程序。

在证明期间,我收到以下警告warning: no Global contract available for "Put_Line"

我已经知道如何将相应的数据依赖关系契约添加到我自己编写的过程和函数中,但是如何将它们添加到其他人编写的程序/函数中,我无法编辑源文件?

我查看了Adacore SPARK 2014用户指南的第5.2和7.4节,但没有找到解决问题的示例。

3 个答案:

答案 0 :(得分:3)

这意味着当调用此函数时,分析器无法“看到”全局变量是否会受到影响。因此,假设此调用没有修改任何内容(否则所有其他证据都可能立即被驳斥)。这可能是您的具体示例的有效假设,但它可能在嵌入式系统上无效,其中Put_Line的自定义实现可能会执行任何操作。

有两种方法可以传达缺失的信息:

  1. 验证程序可以检查函数的源代码。然后它可以尝试自己生成全球合同。
  2. 明确指定全局合同,请参阅RM 6.1.4(http://docs.adacore.com/spark2014-docs/html/lrm/subprograms.html#global-aspects
  3. 在这种情况下,您调用的过程是运行时系统(RTS)的一部分,因此源不可见,您可能不会/不应该更改它。

    在实践中该怎么做?

    抑制警告几乎从来都不是一个好主意,特别是当你在做一些安全关键的工作时。通常必须更改代码,直到警告消失,或者必须启动一些理由过程。

    如果您对分析结果很认真,我建议不要使用这些子程序。如果你真的需要在那里输出,要么编写自己的程序来替换RTS子程序,要么确保子程序确实没有副作用。 Frédéric所链接的内容进一步支持了这一点:即使被调用者没有副作用,也不知道它是否会引发特定输入的异常(例如,非常长的字符串)。

    如果你对结果不那么认真,那么你可以将这个特定的一个视为你可以接受的警告。

答案 1 :(得分:2)

用于开发SPARK应用程序的包装程序包可在此处找到: https://github.com/joakim-strandberg/aida_2012

答案 2 :(得分:1)

我认为您无法在您不拥有的代码上添加Spark合约,尤其是Ada标准的代码。

关于 Text_Io ,我在参考手册中找到了对您有价值的something

修改

根据"Building high integrity applications with Spark" book,与马丁所说的相比,另一种解决方案是创建一个包装器包。

由于Spark要求您处理Spark软件包,但允许您依赖带有Ada主体的Spark规范,解决方案是构建一个包装Ada.Text_io调用的Spark软件包。

这可能是单调乏味的,因为您必须包含可能的异常,可能会定义特定类型等等,但这样,您就可以在完整的Spark程序包中卸载VC。