-
Notifications
You must be signed in to change notification settings - Fork 273
[TG-3581] Better Support for Enums in JBMC #2569
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
Conversation
c5690b2
to
8ca5290
Compare
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 failed Diffblue compatibility checks (cbmc commit: 8ca5290).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/78520669
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
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 failed Diffblue compatibility checks (cbmc commit: c5690b2).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/78520865
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
8ca5290
to
1fe1e37
Compare
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 failed Diffblue compatibility checks (cbmc commit: 1fe1e37).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/78577776
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
@@ -2197,7 +2212,7 @@ void java_bytecode_convert_methodt::convert_invoke( | |||
// generate code that may wrongly assume that such a method is | |||
// accessible if we assume that its access attribute is "more | |||
// accessible" than it actually is. | |||
irep_idt id = arg0.get(ID_identifier); | |||
const irep_idt id = arg0.get(ID_identifier); |
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.
const &
?
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.
it's not clear for me what arg0
represents, if you have an intuition about that can you rename the parameter?
// Also provide a clone method: | ||
// ---------------------------- | ||
|
||
const irep_idt clone_name = identifier + +".clone:()Ljava/lang/Object;"; |
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.
+ +
?
@@ -5,7 +5,6 @@ | |||
Author: Daniel Kroening, [email protected] | |||
|
|||
\*******************************************************************/ | |||
|
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.
spurious change?
@@ -446,184 +445,222 @@ const std::unordered_set<std::string> cprover_methods_to_ignore | |||
"getCurrentThreadID" | |||
}; | |||
|
|||
/// Register in the \p symbol_table a new symbol type | |||
/// java::array[X] where X is byte, float, int, char... | |||
void add_array_type( |
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.
maybe add doxygen for parameters
{ | ||
symbol_typet symbol_type = to_symbol_type(java_array_type(l).subtype()); | ||
|
||
const std::string identifier = enum_name |
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.
you could assign that directly to an irep_idt
@@ -2197,7 +2212,7 @@ void java_bytecode_convert_methodt::convert_invoke( | |||
// generate code that may wrongly assume that such a method is | |||
// accessible if we assume that its access attribute is "more | |||
// accessible" than it actually is. | |||
irep_idt id = arg0.get(ID_identifier); | |||
const irep_idt id = arg0.get(ID_identifier); |
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.
it's not clear for me what arg0
represents, if you have an intuition about that can you rename the parameter?
const bool is_enum_values_clone_call = | ||
enum_clone_symbol.type.get_bool(ID_enumeration) && | ||
(full_method_name == | ||
(calling_class_name + ".values:()[L" + class_type_name + ";")); |
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.
define is_enum_values_clone_call closer to where it is used
if(is_enum_values_clone_call) | ||
{ | ||
const std::string clone_name = | ||
"java::array[" + calling_class_name + "].clone:()Ljava/lang/Object;"; |
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 don't think you can add to a string literal. You should use std::string("java::array[") + ...
instead
code_blockt clone_body; | ||
|
||
code_declt declare_cloned(local_symexpr); | ||
clone_body.move_to_operands(declare_cloned); |
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.
code_blockt has a move method
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.
will change, but this is old code that just moved
|
||
member_exprt new_base_class( | ||
new_array, base_class_component.get_name(), base_class_component.type()); | ||
address_of_exprt retval(new_base_class); |
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.
const?
plus_exprt(old_data, index_symexpr), old_data.type().subtype()); | ||
dereference_exprt new_cell( | ||
plus_exprt(new_data, index_symexpr), new_data.type().subtype()); | ||
code_assignt copy_cell(new_cell, old_cell); |
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.
const?
} | ||
|
||
/// Register in the \p symbol_table a new symbol for an enum type | ||
/// \param enum_type_name: Name of the enum type. |
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.
say that it contains the "java::" prefix?
|
||
#include <java_bytecode/java_utils.h> | ||
|
||
/// Unwind handler that special-cases the clone functions of arrays of |
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.
specializes?
if(is_enum_values_clone_call) | ||
{ | ||
const std::string clone_name = | ||
"java::array[" + class_type_name + "].clone:()Ljava/lang/Object;"; |
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 don't think you can add to a string literal
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 am not sure I understand what you mean, it seems to work without a problem.
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.
It strikes me this can be done more simply if we can expose a bit of symex's state to the loop unwind handlers (called here https://github.com/diffblue/cbmc/blob/develop/src/cbmc/symex_bmc.cpp#L119, and implemented here https://github.com/diffblue/cbmc/blob/develop/jbmc/src/jbmc/jbmc_parse_options.cpp#L508)
Basically we want to inspect a little bit of the calling context, to check whether we're in clone()
, and if so whether this->length
(the length of the array being cloned) is a constant.
Possible approaches:
- Give the unwind handler the ability to call
symext::clean_expr
(which among other things performs constant propagation), so it can directly ask symex forthis->length
and find out whether we know a bound - Annotate the loop! When generating
.clone()
we know the actual loop length is bounded and that bound isthis->length
. Then symex can evaluate the given bound and give it to the unwind handler.
I think either of these would be much simpler and cleaner than method cloning just so we have a unique function ID key to associate with the decision to unwind.
1fe1e37
to
d449275
Compare
@smowton We decided to go with this solution, look at the outcome and look at the alternative in a new issue. |
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 failed Diffblue compatibility checks (cbmc commit: d449275).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/78928253
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
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 acknowledge that this is work-in-progress, but just to jot down my expectations anyway: 1) there need to be tests added; 2) a change to the interpreter has been added, but it's not clear to me how that relates to the PR subject.
const auto &index_symexpr = index_symbol.symbol_expr(); | ||
|
||
code_declt declare_index(index_symexpr); | ||
clone_body.move_to_operands(declare_index); |
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.
clone_body.add(code_declt(...
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.
done
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.
done
|
||
dereference_exprt old_cell( | ||
plus_exprt(old_data, index_symexpr), old_data.type().subtype()); | ||
dereference_exprt new_cell( |
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.
const?
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.
done
please note that this code was just moved, not written by me
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.
done, please note that I mainly moved the code and didn't write it
d449275
to
2a2cef5
Compare
@tautschnig please find some regression tests in the latest commit (these were just in TG before) |
2a2cef5
to
b288c80
Compare
Would it somehow be possible to explain what this is? The change seems entirely sensible to me, but I still don't really get why it would fit this PR. |
6163718
to
17d982d
Compare
@tautschnig this fixes the interpreter when it got a |
these occurred with my PR, but I am not sure whether it was the cause or I just paid more attention to the output here |
For Enum classes this replaces calls to clone via a specialized clone method call that allows for explicit unwind bounds depending on the number of enum elements.
Change argument names to more meaningful identifiers, lint code
This handler unwinds loops in specialized `.clone` functions for `Enum` arrays.
Before we considered the `code_switch_caset` to belong to the target instruction which lead to uncoverable goals of the form: IF condition 1 then GOTO 1 ... 1: GOTO 2 ASSERT false // uncoverable block ... 2:
It could already do index-of-constant-array -- by replacing its custom code with simplify_expr we can expand that to also support member-of-constant-struct, as occurs when symex's deref'ing and then the interpreter's environment translate a variable-length array type like int[obj->length] into int[particular_object.length] and then int[{.length = 1, .data = &xyz}.length].
Update regression tests
17d982d
to
1e01432
Compare
Currently the regression tests fail with symex driven lazy loading due to a difference in generated properties.
1e01432
to
9b82377
Compare
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 failed Diffblue compatibility checks (cbmc commit: 9b82377).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/80539334
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
Proposed alternative implementation here: #2651 |
superseded by #2651 |
Introduce secific unwind bounds for copy loops in array
clone
for enumerations.