-
Notifications
You must be signed in to change notification settings - Fork 280
Library functions: mark them as compiled #8412
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
CORE | ||
main.c | ||
--apply-loop-contracts | ||
^\[ackermann\.\d+\] line 21 Check loop invariant before entry: SUCCESS$ | ||
^\[ackermann\.\d+\] line 21 Check that loop invariant is preserved: SUCCESS$ | ||
^\[ackermann\.\d+\] line 21 Check decreases clause on loop iteration: SUCCESS$ | ||
^\[ackermann.assigns.\d+\] line 29 Check that m is assignable: SUCCESS$ | ||
^\[ackermann.assigns.\d+\] line 30 Check that n is assignable: SUCCESS$ | ||
^\[ackermann.assigns.\d+\] line 35 Check that m is assignable: SUCCESS$ | ||
^\[ackermann.overflow.\d+] line 39 arithmetic overflow on signed \+ in n \+ 1: FAILURE$ | ||
^\*\* 1 of \d+ failed | ||
^VERIFICATION FAILED$ | ||
^EXIT=10$ | ||
^SIGNAL=0$ | ||
-- | ||
-- | ||
It tests whether we can prove (only partially) the termination of the Ackermann | ||
function using a multidimensional decreases clause. | ||
|
||
Note that this particular implementation of the Ackermann function contains | ||
both a while-loop and recursion. Therefore, to fully prove the termination of | ||
the Ackermann function, we must prove both | ||
(i) the termination of the while-loop and | ||
(ii) the termination of the recursion. | ||
Because CBMC does not support termination proofs of recursions (yet), we cannot | ||
prove the latter, but the former. Hence, the termination proof in the code is | ||
only "partial." |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,18 @@ | ||
CORE | ||
main.c | ||
--apply-loop-contracts --replace-call-with-contract ackermann | ||
--replace-call-with-contract ackermann | ||
^\[ackermann.precondition\.\d+\] line \d+ Check requires clause of ackermann in main: SUCCESS$ | ||
^\[ackermann.precondition\.\d+\] line \d+ Check requires clause of ackermann in ackermann: SUCCESS$ | ||
^\[ackermann\.\d+\] line 21 Check loop invariant before entry: SUCCESS$ | ||
^\[ackermann\.\d+\] line 21 Check that loop invariant is preserved: SUCCESS$ | ||
^\[ackermann\.\d+\] line 21 Check decreases clause on loop iteration: SUCCESS$ | ||
^\[ackermann.assigns.\d+\] line 29 Check that m is assignable: SUCCESS$ | ||
^\[ackermann.assigns.\d+\] line 30 Check that n is assignable: SUCCESS$ | ||
^\[ackermann.assigns.\d+\] line 34 Check that n is assignable: SUCCESS$ | ||
^\[ackermann.assigns.\d+\] line 35 Check that m is assignable: SUCCESS$ | ||
^VERIFICATION SUCCESSFUL$ | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
-- | ||
-- | ||
It tests whether we can prove (only partially) the termination of the Ackermann | ||
function using a multidimensional decreases clause. | ||
|
||
Note that this particular implementation of the Ackermann function contains | ||
both a while-loop and recursion. Therefore, to fully prove the termination of | ||
the Ackermann function, we must prove both | ||
(i) the termination of the while-loop and | ||
(ii) the termination of the recursion. | ||
Because CBMC does not support termination proofs of recursions (yet), we cannot | ||
prove the latter, but the former. Hence, the termination proof in the code is | ||
only "partial." | ||
|
||
Furthermore, the Ackermann function has a function contract that the result | ||
The Ackermann function has a function contract that the result | ||
is always non-negative. This post-condition is necessary for establishing | ||
the loop invariant. However, in this test, we do not enforce the function | ||
contract. Instead, we assume that the function contract is correct and use it | ||
(i.e. replace a recursive call of the Ackermann function with its contract). | ||
(i.e. replace a recursive call of the Ackermann function with its contract). | ||
|
||
We cannot verify/enforce the function contract of the Ackermann function, since | ||
CBMC does not support function contracts for recursively defined functions. | ||
As of now, CBMC only supports function contracts for non-recursive functions. | ||
As of now, CBMC only supports function contracts for non-recursive functions. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,26 +41,36 @@ | |
// convert to CFG | ||
if( | ||
library_model.symbol_table.symbols.find(missing_function) != | ||
library_model.symbol_table.symbols.end()) | ||
library_model.symbol_table.symbols.end() && | ||
library_model.symbol_table.lookup_ref(missing_function).value.is_not_nil()) | ||
{ | ||
goto_convert( | ||
missing_function, | ||
library_model.symbol_table, | ||
library_model.goto_functions, | ||
message_handler); | ||
// this function is now included in goto_functions, no need to re-convert | ||
// should the goto binary be reloaded | ||
library_model.symbol_table.get_writeable_ref(missing_function) | ||
.set_compiled(); | ||
tautschnig marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
// We might need a function that's outside our own library, but brought in via | ||
// some header file included by the library. Those functions already exist in | ||
// goto_model.symbol_table, but haven't been converted just yet. | ||
else if( | ||
goto_model.symbol_table.symbols.find(missing_function) != | ||
goto_model.symbol_table.symbols.end()) | ||
goto_model.symbol_table.symbols.end() && | ||
goto_model.symbol_table.lookup_ref(missing_function).value.is_not_nil() && | ||
!goto_model.symbol_table.lookup_ref(missing_function).is_compiled()) | ||
{ | ||
goto_convert( | ||
missing_function, | ||
goto_model.symbol_table, | ||
library_model.goto_functions, | ||
message_handler); | ||
// this function is now included in goto_functions, no need to re-convert | ||
// should the goto binary be reloaded | ||
goto_model.symbol_table.get_writeable_ref(missing_function).set_compiled(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any intuition why our regression tests don't cover this line? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This case would only apply when system headers ship functions marked |
||
} | ||
|
||
// check whether additional initialization may be required | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should
--drop-unused-functions
become the default when running goto-instrument with contracts ?