Skip to content

Unit-test try_evaluate_pointer_comparison and bugfix #4774

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

romainbrenguier
Copy link
Contributor

This adds some unit test for try_evaluate_pointer_comparison, then fix a small bug, and add an unit-test for the case that was buggy, then add some checks for an implicit invariant that I noticed while unit testing, and make value_sett::output more usable in particular for debugging unit tests.

  • Each commit message has a non-empty body, explaining why the change was made.
  • Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
  • [na] The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
  • Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
  • [na] My commit message includes data points confirming performance improvements (if claimed).
  • My PR is restricted to a single feature or bugfix.
  • [na] White-space or formatting changes outside the feature-related changed lines are in commits of their own.

This is so that we can unit-test this function.
@romainbrenguier romainbrenguier force-pushed the unit-test/try-evaluate-pointer-comparison branch from b74ba9d to 4bf2cd5 Compare June 11, 2019 09:35
get_l1_object suggests we are comparing the address of the object, but
the actually should interpret the symbol itself as a pointer.
A unit test for the case of the issue that is fixed will be added in a
following commit.
Field sensitivity the value set to keep track of pointers in individal
fields, making it possible to evaluate equalities such as the one in the
example.
This is a case which would not work if try_evaluate_pointer_comparisons
was using get_l1_object_identifier instead of getting the identifier of
the whole l1 expression (not the underlying object).

fixup! Check pointer evaluation in the array case
@romainbrenguier romainbrenguier force-pushed the unit-test/try-evaluate-pointer-comparison branch from 4bf2cd5 to 017cd09 Compare June 11, 2019 10:06
@@ -1220,7 +1221,8 @@ void value_sett::assign(
std::cout << "--------------------------------------------\n";
output(ns, std::cout);
#endif

PRECONDITION(is_l1_renamed(lhs));
Copy link
Contributor

Choose a reason for hiding this comment

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

This is only true when used in symex-- otherwise we expect to operate on plain un-renamed expressions. Therefore these invariants should move to symex_dereference or to some wrapper function in goto_statet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I defined a wrapper class for value_sett (a wrapper function wouldn't ensure we didn't continue to use the unchecked one)

Copy link
Contributor

@owen-mc-diffblue owen-mc-diffblue left a comment

Choose a reason for hiding this comment

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

Great unit tests. Some other edge cases you might want to consider testing: if the value-set contains ID_unknown, ID_invalid or a failed symbol then try_evaluate_pointer_comparison should not be able to determine anything.

@romainbrenguier romainbrenguier force-pushed the unit-test/try-evaluate-pointer-comparison branch 2 times, most recently from b056982 to 2253cbd Compare June 11, 2019 15:19
@romainbrenguier
Copy link
Contributor Author

@owen-jones-diffblue I added some cases in the unit test, in particular some with unknown in the value set.

@owen-mc-diffblue
Copy link
Contributor

Btw failed symbols are covered by the regression test that was merged in #4659, I believe.


/// Wrapper for value_sett which ensures we access it in a consistent way.
/// In particular level 1 names should be used.
class symex_value_sett : value_sett
Copy link
Contributor

Choose a reason for hiding this comment

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

Generally prefer composition to inheritence

@@ -222,13 +138,13 @@ renamedt<ssa_exprt, L2> goto_symex_statet::assignment(
ssa_exprt l1_lhs(lhs);
l1_lhs.remove_level_2();

if(run_validation_checks)
Copy link
Contributor

Choose a reason for hiding this comment

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

These should still be guarded by if(run_validation_checks)

Copy link
Collaborator

@tautschnig tautschnig left a comment

Choose a reason for hiding this comment

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

This PR appears to be doing at least 3 different things (and some of them I believe are wrong, see detailed comments).

@@ -14,9 +14,6 @@ Author: Romain Brenguier, [email protected]
#include <util/std_expr.h>
bool is_l1_renamed(const exprt &expr)
{
if(!is_l2_renamed(expr.type()))
return false;
Copy link
Collaborator

Choose a reason for hiding this comment

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

The claim made in the commit message seems wrong: the type may well be renamed to L2 even when the object itself is only L1. On the contrary, it actually makes no sense for the type to be renamed to L1 ever.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok I didn't know that the type could be L2 while the object L1. But is it true that L1 object always have L2 types? It sounds wrong to me. It seems that when an ssa_exprt is renamed to L1, its type is also renamed to L1.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Renaming to L1 effectively is instantiation/determines which instance of a named object we are using. At that point the type must be complete, i.e., must be L2.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems to be the case in symex_decl but not in symex_dereference and the other places where L1 renaming is used. Should we make rename<L1> apply L2 renaming on the type to ensure this is consistent?

@@ -22,6 +22,8 @@ Author: Daniel Kroening, [email protected]

#include <langapi/language_util.h>
#include <util/range.h>
#include <util/format_expr.h>
#include <util/format_type.h>
Copy link
Collaborator

Choose a reason for hiding this comment

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

But then #include <langapi/language_util.h> better be removed as well (and hopefully also the corresponding entry in module_dependencies.txt).

@@ -20,10 +20,11 @@ Author: Daniel Kroening, [email protected]
#include <util/prefix.h>
#include <util/simplify_expr.h>

#include <goto-symex/renamed.h>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think a dependency from pointer-analysis towards goto-symex is right.

@romainbrenguier
Copy link
Contributor Author

@tautschnig

This PR appears to be doing at least 3 different things (and some of them I believe are wrong, see detailed comments).

Yes you are right, I extracted what comes after the unit tests and bugfix into a new pull request
#4778 so that we can merge the fix more quickly and leave time for discussion on the other part.

Copy link
Contributor

@allredj allredj left a comment

Choose a reason for hiding this comment

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

✔️
Passed Diffblue compatibility checks (cbmc commit: e26f4cd).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/115206278

@codecov-io
Copy link

codecov-io commented Jun 12, 2019

Codecov Report

❗ No coverage uploaded for pull request base (develop@c63c167). Click here to learn what that means.
The diff coverage is 99.18%.

Impacted file tree graph

@@            Coverage Diff             @@
##             develop    #4774   +/-   ##
==========================================
  Coverage           ?   68.62%           
==========================================
  Files              ?     1276           
  Lines              ?   105155           
  Branches           ?        0           
==========================================
  Hits               ?    72162           
  Misses             ?    32993           
  Partials           ?        0
Impacted Files Coverage Δ
src/goto-symex/goto_symex.h 92.3% <ø> (ø)
src/goto-symex/symex_goto.cpp 94.82% <100%> (ø)
...it/goto-symex/try_evaluate_pointer_comparisons.cpp 99.15% <99.15%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c63c167...767d8f0. Read the comment docs.

This test the case where ptr1 can point to value1 or value2 and we
evaluate `ptr1 != &value1`
This check the case where ptr1 is either &value1 or &value2 and we
compare it to null.
This adds a unit test for the case where the value set contains
unknown. In that case no comparison can be decided.
@romainbrenguier romainbrenguier force-pushed the unit-test/try-evaluate-pointer-comparison branch from 6f1891d to 767d8f0 Compare June 12, 2019 08:58
Copy link
Contributor

@allredj allredj left a comment

Choose a reason for hiding this comment

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

✔️
Passed Diffblue compatibility checks (cbmc commit: 767d8f0).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/115226966

@tautschnig tautschnig merged commit 6514482 into diffblue:develop Jun 14, 2019
@romainbrenguier romainbrenguier deleted the unit-test/try-evaluate-pointer-comparison branch June 17, 2019 07:44
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.

6 participants