-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unprovable checks with size constraint for successor #974
Comments
rflx-test-message.ads:501:99: medium: overflow check might fail
501 | RFLX_Types.U64 (Get_Length (Ctx)) * 8 >= RFLX_Types.U64 (Field_Last (Ctx, F_Hash)) - RFLX_Types.U64 (Field_First (Ctx, F_Count)) + 17
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
reason for check: result of subtraction must fit in a 64-bits machine integer
possible fix: use pragma Overflow_Mode or switch -gnato13 or unit Ada.Numerics.Big_Numerics.Big_Integers
rflx-test-message.ads:501:145: medium: overflow check might fail
501 | RFLX_Types.U64 (Get_Length (Ctx)) * 8 >= RFLX_Types.U64 (Field_Last (Ctx, F_Hash)) - RFLX_Types.U64 (Field_First (Ctx, F_Count)) + 17
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
reason for check: result of addition must fit in a 64-bits machine integer
possible fix: use pragma Overflow_Mode or switch -gnato13 or unit Ada.Numerics.Big_Numerics.Big_Integers
rflx-test-message.ads:626:99: medium: overflow check might fail
626 | RFLX_Types.U64 (Get_Length (Ctx)) * 8 >= RFLX_Types.U64 (Field_Last (Ctx, F_Hash)) - RFLX_Types.U64 (Field_First (Ctx, F_Count)) + 17
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
reason for check: result of subtraction must fit in a 64-bits machine integer
possible fix: use pragma Overflow_Mode or switch -gnato13 or unit Ada.Numerics.Big_Numerics.Big_Integers
rflx-test-message.ads:626:145: medium: overflow check might fail
626 | RFLX_Types.U64 (Get_Length (Ctx)) * 8 >= RFLX_Types.U64 (Field_Last (Ctx, F_Hash)) - RFLX_Types.U64 (Field_First (Ctx, F_Count)) + 17
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
reason for check: result of addition must fit in a 64-bits machine integer
possible fix: use pragma Overflow_Mode or switch -gnato13 or unit Ada.Numerics.Big_Numerics.Big_Integers
rflx-test-message.ads:820:128: medium: overflow check might fail
820 | and then RFLX_Types.U64 (Cursors (F_Length).Value) * 8 >= RFLX_Types.U64 (Cursors (F_Hash).Last) - RFLX_Types.U64 (Cursors (F_Count).First) + 17)))
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
reason for check: result of subtraction must fit in a 64-bits machine integer
possible fix: add precondition (RFLX_Types.U64 (Cursors (F_Hash).Last) >= U64'First + RFLX_Types.U64 (Cursors (F_Count).First)) to subprogram at line 780
780 | function Valid_Context (Buffer_First, Buffer_Last : RFLX_Types.Index; First : RFLX_Types.Bit_Index; Last : RFLX_Types.Bit_Length; Verified_Last : RFLX_Types.Bit_Length; Written_Last : RFLX_Types.Bit_Len
gth; Buffer : RFLX_Types.Bytes_Ptr; Cursors : Field_Cursors) return Boolean is
| ^ here
rflx-test-message.ads:820:171: medium: overflow check might fail
820 | and then RFLX_Types.U64 (Cursors (F_Length).Value) * 8 >= RFLX_Types.U64 (Cursors (F_Hash).Last) - RFLX_Types.U64 (Cursors (F_Count).First) + 17)))
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
reason for check: result of addition must fit in a 64-bits machine integer
possible fix: add precondition (RFLX_Types.U64 (Cursors (F_Hash).Last) - RFLX_Types.U64 (Cursors (F_Count).First) <= U64'Last - 17) to subprogram at line 780
780 | function Valid_Context (Buffer_First, Buffer_Last : RFLX_Types.Index; First : RFLX_Types.Bit_Index; Last : RFLX_Types.Bit_Length; Verified_Last : RFLX_Types.Bit_Length; Written_Last : RFLX_Types.Bit_Len
gth; Buffer : RFLX_Types.Bytes_Ptr; Cursors : Field_Cursors) return Boolean is
| ^ here
rflx-test-message.ads:905:83: medium: precondition might fail, cannot prove Available_Space (Ctx, Fld) >= Field_Size (Ctx, Fld)
905 | RFLX_Types.U64 (Ctx.Cursors (F_Length).Value) * 8 >= RFLX_Types.U64 (Field_Last (Ctx, F_Hash)) - RFLX_Types.U64 (Ctx.Cursors (F_Count).First) + 17,
| ^~~~~~~~~~~~~~~~~~~~~~~ No failing checks occur, if the condition |
At least all overflow checks vanish when removing unnecessary type conversions to @@ -498,7 +498,7 @@
and Structural_Valid (Ctx, F_Hash)
and Invalid (Ctx, F_Structs)
and (if
- RFLX_Types.U64 (Get_Length (Ctx)) * 8 >= RFLX_Types.U64 (Field_Last (Ctx, F_Hash)) - RFLX_Types.U64 (Field_First (Ctx, F_Count)) + 17
+ RFLX_Types.Bit_Length (Get_Length (Ctx)) * 8 >= Field_Last (Ctx, F_Hash) - Field_First (Ctx, F_Count) + 17
then
Predecessor (Ctx, F_Structs) = F_Hash
and Valid_Next (Ctx, F_Structs))
@@ -553,7 +553,7 @@
and Structural_Valid (Ctx, F_Hash)
and Invalid (Ctx, F_Structs)
and (if
- RFLX_Types.U64 (Get_Length (Ctx)) * 8 >= RFLX_Types.U64 (Field_Last (Ctx, F_Hash)) - RFLX_Types.U64 (Field_First (Ctx, F_Count)) + 17
+ RFLX_Types.Bit_Length (Get_Length (Ctx)) * 8 >= Field_Last (Ctx, F_Hash) - Field_First (Ctx, F_Count) + 17
then
Predecessor (Ctx, F_Structs) = F_Hash
and Valid_Next (Ctx, F_Structs))
@@ -623,7 +623,7 @@
Context_Cursors_Index (Context_Cursors (Ctx), F) = Context_Cursors_Index (Context_Cursors (Ctx)'Old, F)),
others =>
(if
- RFLX_Types.U64 (Get_Length (Ctx)) * 8 >= RFLX_Types.U64 (Field_Last (Ctx, F_Hash)) - RFLX_Types.U64 (Field_First (Ctx, F_Count)) + 17
+ RFLX_Types.Bit_Length (Get_Length (Ctx)) * 8 >= Field_Last (Ctx, F_Hash) - Field_First (Ctx, F_Count) + 17
then
Predecessor (Ctx, F_Structs) = F_Hash
and Valid_Next (Ctx, F_Structs))
@@ -817,7 +817,7 @@
then
(Structural_Valid (Cursors (F_Hash))
and then Cursors (F_Structs).Predecessor = F_Hash
- and then RFLX_Types.U64 (Cursors (F_Length).Value) * 8 >= RFLX_Types.U64 (Cursors (F_Hash).Last) - RFLX_Types.U64 (Cursors (F_Count).First) + 17)))
+ and then RFLX_Types.Bit_Length (Cursors (F_Length).Value) * 8 >= Cursors (F_Hash).Last - Cursors (F_Count).First + 17)))
and then ((if Invalid (Cursors (F_Count)) then Invalid (Cursors (F_Length)))
and then (if Invalid (Cursors (F_Length)) then Invalid (Cursors (F_Hash)))
and then (if Invalid (Cursors (F_Hash)) then Invalid (Cursors (F_Structs))))
@@ -841,7 +841,7 @@
and then Cursors (F_Hash).First = Cursors (F_Length).Last + 1
and then (if
Structural_Valid (Cursors (F_Structs))
- and then RFLX_Types.U64 (Cursors (F_Length).Value) * 8 >= RFLX_Types.U64 (Cursors (F_Hash).Last) - RFLX_Types.U64 (Cursors (F_Count).First) + 17
+ and then RFLX_Types.Bit_Length (Cursors (F_Length).Value) * 8 >= Cursors (F_Hash).Last - Cursors (F_Count).First + 17
then
Cursors (F_Structs).Last - Cursors (F_Structs).First + 1 = RFLX_Types.Bit_Length (Cursors (F_Length).Value) * 8 - 16 + ((-RFLX_Types.Bit_Length (Cursors (F_Hash).Last)) + RFLX_Types.Bit_Length (Cursors (F_Count).First) - 1)
and then Cursors (F_Structs).Predecessor = F_Hash
@@ -895,14 +895,14 @@
when F_Initial | F_Count | F_Length | F_Structs | F_Final =>
True,
when F_Hash =>
- RFLX_Types.U64 (Ctx.Cursors (F_Length).Value) * 8 >= RFLX_Types.U64 (Ctx.Cursors (F_Hash).Last) - RFLX_Types.U64 (Ctx.Cursors (F_Count).First) + 17));
+ RFLX_Types.Bit_Length (Ctx.Cursors (F_Length).Value) * 8 >= Ctx.Cursors (F_Hash).Last - Ctx.Cursors (F_Count).First + 17));
function Field_Condition (Ctx : Context; Fld : Field; Val : RFLX_Types.U64) return Boolean is
((case Fld is
when F_Count | F_Length =>
True,
when F_Hash =>
- RFLX_Types.U64 (Ctx.Cursors (F_Length).Value) * 8 >= RFLX_Types.U64 (Field_Last (Ctx, F_Hash)) - RFLX_Types.U64 (Ctx.Cursors (F_Count).First) + 17,
+ RFLX_Types.Bit_Length (Ctx.Cursors (F_Length).Value) * 8 >= Field_Last (Ctx, F_Hash) - Ctx.Cursors (F_Count).First + 17,
when F_Structs =>
True)); I also observed that SPARK is able to easily prove There are still some unproved checks after that change: rflx-test-message.adb:295:32: medium: postcondition might fail, cannot prove Path_Condition (Ctx, Fld)
295 | and Valid_Next (Ctx, F_Structs)),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
in inlined expression function body at rflx-test-message.ads:954
rflx-test-message.ads:503:16: medium: postcondition might fail, cannot prove Predecessor (Ctx, F_Structs) = F_Hash
503 | Predecessor (Ctx, F_Structs) = F_Hash
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
possible fix: call at rflx-test-message.adb:363 should mention Buffer (for argument Ctx) in a postcondition
363 | Test.My_Seq.Copy (Seq_Ctx, Ctx.Buffer.all (Buffer_First .. Buffer_Last));
| ^ here
rflx-test-message.ads:624:16: medium: contract case might fail
624 | others =>
| ^ here
rflx-test-message.ads:905:74: medium: precondition might fail, cannot prove Available_Space (Ctx, Fld) >= Field_Size (Ctx, Fld)
905 | RFLX_Types.Bit_Length (Ctx.Cursors (F_Length).Value) * 8 >= Field_Last (Ctx, F_Hash) - Ctx.Cursors (F_Count).First + 17,
| ^~~~~~~~~~~~~~~~~~~~~~~ |
Indeed SPARK doesn't like mixing signed and unsigned arithmetic, and would rather stay in one or the other. That's something I discussed with Yannick last week, it could be generally beneficial to reduce the amount of signed integer types in generated code. I will try your patch. |
I FINALLY made some progress on this ticket. As I said, SPARK doesn't like the mix of signed/unsigned computations which result from the fact that the data is unsigned (in U64), but computations happen in signed types. In particular cvc4 struggles with this and doesn't prove much on this code (z3 copes remarkably well). As an experiment, I replaced U64 by a kind of "S63" type, that is something like that:
and use it in the same way that we use U64 in the file for the The one VC that's still unproved is this:
cvc4 and z3 both return "unknown" immediately, which makes me think there is information missing. To be checked. |
Glad you have made some progress. I'm wondering if it would be possible to let SPARK interpret the |
It's possible (unsigned integers were mapped to mathematical integers before provers supported bitvectors), but it's quite ingrained in the tool and I expect it's difficult to add the functionality you describe. I wouldn't expect it in the short term. |
The following RecordFlux spec results in unprovable overflow checks and unprovable conditions:
One example is the postcondition of
Set
, indeed I don't see any conditions that would protect the computation against overflow, and I don't see any reason for the condition to hold.Could it be that the condition should be for the
Structs
field and not theHash
field in the postcondition? That would seem more reasonable at first glance.The text was updated successfully, but these errors were encountered: