Skip to content

[depends: #1161, #1272] JSON expr and JSON trace #1271

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

Closed
wants to merge 37 commits into from

Conversation

tautschnig
Copy link
Collaborator

None of this is my work - these are commits already merged into develop (test-gen-support).

/// Replaces in src, expressions of the form pointer_offset(constant) by that
/// constant.
/// \param src: an expression
void remove_pointer_offsets(exprt &src)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

util/simplify_expr should be improved to do that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #1288.

@@ -21,11 +22,13 @@ class namespacet;

json_objectt json(
const exprt &,
const namespacet &);
const namespacet &,
const irep_idt &mode=ID_unknown);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default arguments should be avoided.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in #1288.


#include <langapi/mode.h>

static exprt simplify_json_expr(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

util/simplify_expr should be improved to do that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in #1288.

if(src.id()==ID_pointer_offset &&
src.op0().id()==ID_constant &&
src.op0().op0().id()==ID_address_of &&
src.op0().op0().op0().id()==ID_index)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@romainbrenguier Would you happen to know where you had seen such expressions? (This originally was f4fa778.) As far as I am aware, an expression with id ID_constant should not have any operands.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are symbolic pointer constants -- for example, constant(value -> 0x12345678, op0 -> &dynamic_object1), giving both the bitwise and the symbolic value. They only occur in traces AFAIK.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I'd be quite surprised by a case where this worked, but the above more general function didn't.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot, finally I do understand and should have done so all along as I happened to edit code recently... Quite possibly we should have a pointer_constant_exprt or the likes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the constant operands does not only happen in traces but in other places as well, I will try to find some example...
I agree how expressions deal with pointers is a bit messy at the moment but I'm not sure about pointer_constant_exprt, why not having simply a constant of type pointer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it seems that constant operands is something coming from the solver: if I understand correctly calling get on an expression returns a constant with value corresponding to its actual value and an operand with the original expression.
One thing that confused me a bit is that expressions like &a[0] gets simplified by from_expr to a, but simplify_expr does not simplify it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that confused me a bit is that expressions like &a[0] gets simplified by from_expr to a, but simplify_expr does not simplify it.

That's because as much as they can be used interchangeably at source level, their types are different: with int a[1], a is of type int[1], while &a[0] is of type int*. Consequently the pretty printer can do this "simplification" at text level, but transforming expressions would not be valid.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok thanks, it makes more sense to me now

}
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is exceptions20 included deliberately?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is a merge error, I will review how this crept in.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, no, not quite: this appears to be the regression test affiliated with d299ea2. Do you think this is not a good fit for this PR?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I forgot about that and wondered what is has to do with JSON. ok for inclusion then.

@tautschnig tautschnig mentioned this pull request Aug 23, 2017
@tautschnig tautschnig changed the title [develop->master] JSON expr and JSON trace [depends: #1288, develop->master] JSON expr and JSON trace Aug 23, 2017
@tautschnig
Copy link
Collaborator Author

I will need to debug why the "outputID" entry is missing from the test output (failing CI test).

Copy link
Contributor

@smowton smowton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concerned about some of those simplifications. I expect some of them are deliberately unsound but look pretty, and therefore they should not go into simplify_expr.

if(src.id()==ID_pointer_offset &&
src.op0().id()==ID_constant &&
src.op0().op0().id()==ID_address_of &&
src.op0().op0().op0().id()==ID_index)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are symbolic pointer constants -- for example, constant(value -> 0x12345678, op0 -> &dynamic_object1), giving both the bitwise and the symbolic value. They only occur in traces AFAIK.

if(src.id()==ID_pointer_offset &&
src.op0().id()==ID_constant &&
src.op0().op0().id()==ID_address_of &&
src.op0().op0().op0().id()==ID_index)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I'd be quite surprised by a case where this worked, but the above more general function didn't.

src.operands().size()==1 &&
src.op0().id()!=ID_constant)
// try to simplify the constant pointer
return simplify_json_expr(src.op0(), ns);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommend improve this comment -- this is discarding the binary value of the pointer, keeping only the symbolic expression. It is not a simplification per se.

src.op0()).get_component_name()).find("@")!=std::string::npos)
{
// simplify expressions of the form &member_expr(object, @class_identifier)
return simplify_json_expr(src.op0(), ns);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!!! This transforms ``&x.@xyzintox.@xyz`, changing its type!

to_index_expr(src.op0()).index()).value_is_zero_string())
{
// simplify expressions of the form &array[0]
return simplify_json_expr(to_index_expr(src.op0()).array(), ns);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

! &arr[0] has type element* whereas arr has type element[...], might be important?

@tautschnig
Copy link
Collaborator Author

Concerned about some of those simplifications. I expect some of them are deliberately unsound but look pretty, and therefore they should not go into simplify_expr.

Are there tests or other bits of information that could be used for validation purposes? @romainbrenguier would you know more about this? You seem to have authored the original commits introducing those changes, unless I'm mistaken. If anyone else has input, please do contribute.

@peterschrammel
Copy link
Member

The typical use case of these simplifications is regression/cbmc-java/json_trace3 where array access expressions that entirely consist of constants should be simplified to the value expression of the accessed array element, e.g. {10, 11, 12, 13}[(0+8)/4)]=12 for a 32-bit int array.

@romainbrenguier
Copy link
Contributor

romainbrenguier commented Aug 25, 2017

Actually there is a regression test which was supposed to check the original changes in regression/strings-smoke-tests/jsonArrays but it has been changed and it seems to be broken as we see some unknown values assigned:

         {
          "assignmentType": "variable",
          "hidden": true,
          "internal": false,
          "lhs": "tmp_object_factory$5",
          "mode": "java",
          "sourceLocation": {
            "file": "test.java",
            "function": "java::test.check:(Ljava/lang/String;)I",
            "line": "5"
          },
          "stepType": "assignment",
          "thread": 0,
          "value": {
            "name": "unknown"
          }
        },

It seems the value reported as unknown is a with_expr representing an array and not handled by json, it wouldn't be handled by the functions removed by this PR either, so it should not block this PR and we should create a new issue for that (TG-393) .

@tautschnig tautschnig changed the title [depends: #1288, develop->master] JSON expr and JSON trace [depends: #1288] JSON expr and JSON trace Sep 2, 2017
@tautschnig tautschnig changed the title [depends: #1288] JSON expr and JSON trace JSON expr and JSON trace Sep 2, 2017
@tautschnig tautschnig changed the title JSON expr and JSON trace [depends: #1161] JSON expr and JSON trace Sep 2, 2017
romainbrenguier and others added 22 commits September 2, 2017 10:30
json() does not deal with nil expression and would just give "name" :
"unknown". On the other hand nil expression should not make it to that
stage so it would probably denotes an error.
This will delete language pointer created by get_language_from_mode
when the object goes out of scope.
This prevents memory leaks when using json output.
We simplifying these expression so that these pointers appear correctly
in the trace in json.
This is related to issue diffblue/test-gen#21

Includes improvements in json_expr.cpp following review of PR#922
We simplify expressions containing array accesses before producing a
json representation of the trace.
This commit also adds comments on the functions in the cpp files

Includes improvements in json_goto_trace.cpp following review of PR#922
This previously stripped pointer_offset_exprt, which wasn't correct--
it should mask the pointer expression within it to give the offset
between the operand address and the base of its allocation.
With the exception_value support, there is the possibility to have `nil` values
assigned in the trace. These values are returned from `prop_conv.get(expr)`.
In particular, booleans are now printed as true/false instead of 0/1;
NULL as null, and pointer types as their respective structs.
@tautschnig tautschnig changed the title [depends: #1161] JSON expr and JSON trace [depends: #1161, #1272] JSON expr and JSON trace Sep 2, 2017
@thk123 thk123 requested review from chrisr-diffblue and removed request for thk123 October 31, 2017 12:57
@tautschnig
Copy link
Collaborator Author

All the discussion items seem to have been merged into develop, closing this as a transition to master will likely happen differently.

@tautschnig tautschnig closed this Feb 23, 2018
@tautschnig tautschnig deleted the json-trace branch February 23, 2018 13:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants