-
Notifications
You must be signed in to change notification settings - Fork 274
Bug fix using format
function on code_declt
containing initialization
#5833
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
Bug fix using format
function on code_declt
containing initialization
#5833
Conversation
This was previously unimplemented, which resulted in the part of the statement being missing from the formatted output.
To confirm the functionality added is correct and continues to work when follow up refactorings are applied.
So that the initial value can be read out of a `code_declt` without directly accessing the operands.
To avoid directly reading from the operands.
So that the initial value can be written to a `code_declt` without directly accessing the operands.
To avoid directly writing to the operands of a `code_declt`.
To avoid repeatedly checking the same condition and so that `value` is only in scope where it is required and non-empty.
To avoid directly setting the operands.
To avoid directly accessing the operands.
Codecov Report
@@ Coverage Diff @@
## develop #5833 +/- ##
===========================================
+ Coverage 72.85% 72.86% +0.01%
===========================================
Files 1423 1422 -1
Lines 154072 154194 +122
===========================================
+ Hits 112244 112357 +113
- Misses 41828 41837 +9
Continue to review full report at Codecov.
|
The weakest precondition computation here assumes no initial value for a This function would also need an update -- it currently ignores the initial value, even if it's present. There might be more such cases elsewhere in the codebase? |
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.
I suppose I find it a bit surprising that we have initialisers in code_declt
s to begin with.
|
||
/// Sets the value to which this declaration initializes the declared | ||
/// variable. Empty optional maybe passed to remove existing initialisation. | ||
void set_initial_value(optionalt<exprt> initial_value) |
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.
If these can exist with optional initial_value
s then I'd much prefer we had a constructor that took an initial value as the argument rather than having a separate setter.
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.
All the examples I have found so far were mutating after construction. I could add the facility to set this via the constructor as well.
This PR doesn't make any changes to what data is present. I assume that function currently works due to the assignment/initialisation being separated out before the function is reached. I have tried adding a precondition in that function to initialisation not being in the declaration and all tests passed. So I may tack that change onto this PR, or add it as a separate follow-up PR. |
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.
This PR makes me concerned. Not because of what it does as such but more because of the context. I think you have uncovered one of the historic ambiguities over what, exactly, a well-formed goto_programt
is.
I /guess/ what has happened is:
DECL
instructions used to have an initialiser statement.- At some point it was decided to simplify things by having
DECL
be just declaration and initialisation being done with a followingASSIGN
. - Most of the code was converted over to split up initialisation. Some older, at-the-time untested, code was left. Also the option was not removed from
goto_programt
for some reason (backwards compatibility, overlooked, forgotten?).
So, perhaps the question I would ask is not /does/ it have initialisers but /should/ it have initialisers. Personally I would say no because:
- Quite a bit of the code doesn't support it, it would be a non-trivial effort to do so.
- AFAIK it is not currently widely used.
- Orthogonality and simplicity in
goto_programt
is good because it makes analysis code easier to write.
So, sorry @thomasspriggs for hijacking what seems like a good and simple tidy up but ... should we just remove this all together?
Some of the comments imply that people have found sections of the code that do / don't take these initialisers into account. It might help the discussion if you could post links to these.
I agree that it would be good to be certain whether it is or is not valid to include this on a
My concern with trying to remove this altogether is that it is going to be difficult to be sure that we have found and removed all usages.
The usages which I have looked at so far are either touched by this PR already, or mentioned in Saswat's comment. |
Just a quick thought: should we introduce something like |
This function does not account for the case where a code_declt contains `initialization`. Given that the test suite passes with this PRECONDITION is in place, such statements must be separated out before this function is reached. Should this condition be violated in future, then the CONDITION can be removed and the handling of this case implemented.
Or a |
Initializations must be sepearated out of `code_declt` into a separate assignment before adding to goto program. This is the case already. These new INVARIANTs check that this continues to be true.
@martin-cs I have investigated a bit further and found that declarations which initialise are produced by the C front end. I have added additional commits which add invariants/preconditions to disallow the declarations in goto-programs from containing initialisations as these should be removed by this point. Please can you re-review? If the clean-up which is in this PR is controversial then I can drop all but the first two commits from it. I do want to get the fix to |
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.
I think this is a reasonable intermediate fix, but the long-term route should likely be one of having a separate some_variant_of_declt
class that's to be used by the front-end.
const auto &decl = expr_checked_cast<code_declt>(code); | ||
INVARIANT( | ||
!decl.initial_value(), | ||
"code_declt in goto program may not contain initialization."); | ||
return decl; |
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.
While the INVARIANT
in set_decl
is probably the right thing, this one may better be placed in goto_programt::instructiont::validate
.
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.
Given that this PR is now approved, I am going to merge as is and clean up this as a follow-up PR.
Bug fix using
format
function oncode_declt
containing initialization. Functionality was previously unimplemented, which resulted in part of the statement being missing from the formatted output.The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/My commit message includes data points confirming performance improvements (if claimed).