Skip to content

Well-formedness checking of SSA equation [depends on #3480] #3287

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

Merged
merged 2 commits into from
Dec 1, 2018

Conversation

xbauch
Copy link
Contributor

@xbauch xbauch commented Nov 7, 2018

This is an attempt at introducing well-formedness checking into SSA equation. It follows the process of #3123 by implementing the validate method in SSA_stept and extending ssa_exprt with check/validate functionality. Unit tests will be included if the attempt is deemed worthy of pursuing.

  • 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.
  • 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).
  • My commit message includes data points confirming performance improvements (if claimed).
  • My PR is restricted to a single feature or bugfix.
  • White-space or formatting changes outside the feature-related changed lines are in commits of their own.

@xbauch xbauch changed the title Feature/ssa validate Well-formedness checking of SSA equation Nov 7, 2018
Copy link
Contributor

@danpoe danpoe left a comment

Choose a reason for hiding this comment

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

Looks good so far, a few minor comments

if(cmdline.isset("validate-ssa-equation"))
{
options.set_option("validate-ssa-equation", true);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This should best be put in cbmc_parse_optionst::get_command_line_options()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

DATA_CHECK(!has_operands(), "SSA expression do not have operands");
DATA_CHECK(id() == ID_symbol, "SSA expression symbols are symbols");
DATA_CHECK(get_bool(ID_C_SSA_symbol), "wrong SSA expression ID");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Btw, these methods have now become static methods that take the parent type in the recent changes to PR #3123. So that would then become static void check(const exprt &expr, const validation_modet vm).

We should also add a case for SSA_exprt to call_on_expr() in validate_expressions.cpp.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


void check(const validation_modet vm = validation_modet::INVARIANT) const
{
DATA_CHECK(!has_operands(), "SSA expression do not have operands");
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: According to the coding standard (cbmc/CODING_STANDARD.md), if possible the messages in invariants should be "should" statements that describe what should hold, e.g. "SSA expression should have operands".

@@ -125,8 +125,29 @@ int goto_instrument_parse_optionst::doit()

get_goto_program();

{
const bool b = cmdline.isset("validate-goto-binary");
Copy link
Member

Choose a reason for hiding this comment

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

What does b stand for?

@@ -1572,6 +1593,12 @@ void goto_instrument_parse_optionst::help()
" --show-local-safe-pointers show pointer expressions that are trivially dominated by a not-null check\n" // NOLINT(*)
" --show-safe-dereferences show pointer expressions that are trivially dominated by a not-null check\n" // NOLINT(*)
" *and* used as a dereference operand\n" // NOLINT(*)
// NOLINTNEXTLINE(whitespace/line_length)
Copy link
Member

Choose a reason for hiding this comment

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

I suggest to provide HELP_VALIDATION and OPT_VALIDATION to avoid code duplication.

}
};

#endif /* CPROVER_UTIL_VALIDATE_H */
Copy link
Member

Choose a reason for hiding this comment

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

// preferred

const namespacet &ns,
const validation_modet vm);

#endif /* CPROVER_UTIL_VALIDATE_CODE_H */
Copy link
Member

Choose a reason for hiding this comment

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

// preferred

const namespacet &ns,
const validation_modet vm);

#endif /* CPROVER_UTIL_VALIDATE_EXPRESSIONS_H */
Copy link
Member

Choose a reason for hiding this comment

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

// preferred

const namespacet &ns,
const validation_modet vm);

#endif /* CPROVER_UTIL_VALIDATE_TYPES_H */
Copy link
Member

Choose a reason for hiding this comment

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

// preferred

class namespacet;
enum class validation_modet;

void check_type_pick(const typet &type, const validation_modet vm);
Copy link
Member

Choose a reason for hiding this comment

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

Parameter names could be omitted in the declarations. It's obvious what they are.

{
const namespacet ns(goto_model.symbol_table);
goto_model.validate(ns, validation_modet::INVARIANT);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this from a previous PR as it doesn't match the description of the PR?

@@ -406,6 +406,12 @@ int goto_analyzer_parse_optionst::doit()
if(process_goto_program(options))
return CPROVER_EXIT_INTERNAL_ERROR;

if(cmdline.isset("validate-goto-model"))
{
Copy link
Collaborator

Choose a reason for hiding this comment

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

So, I'm opinionated but ... why add this option to every program? Why not just add it to goto-instrument? If it's the same check (and eventually everyone will do it on program load) why do we need the extra option everywhere?

@xbauch
Copy link
Contributor Author

xbauch commented Nov 9, 2018

Rebased onto #3123 branch to follow the latest version. Only the last commit pertain to SSA checking. Once #3123 is merged into develop, this will be rebased onto that and hopefully cleaner.

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.

Some comments below, but the biggest item that I'd like to see added/changed is the current check_renaming of goto_symex_state.cpp to be moved into the validation framework and thus only done when validation is enabled.

validate_full_expr(ssa_full_lhs, ns, vm);
validate_full_expr(original_full_lhs, ns, vm);
validate_full_expr(ssa_rhs, ns, vm);
base_type_eq(ssa_lhs.get_original_expr(), ssa_rhs, ns);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This has no effect?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, my bad: this was intended to check that lhs and rhs have the same type. Should be fixed now.

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: ea8c694).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91355754

@xbauch
Copy link
Contributor Author

xbauch commented Nov 15, 2018

@tautschnig regarding the check_renaming: I've tried moving this check into the validation framework. I ended up adding a validation_modet variable to both goto_symext and goto_symex_statet and an IGNORE validation mode. Have a look if this is what you had in mind.

@@ -76,7 +76,8 @@ class goto_symext
path_storage(path_storage),
path_segment_vccs(0),
_total_vccs(std::numeric_limits<unsigned>::max()),
_remaining_vccs(std::numeric_limits<unsigned>::max())
_remaining_vccs(std::numeric_limits<unsigned>::max()),
global_validation_mode(validation_modet::IGNORE)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wouldn't it be possible to look at options instead and store that in a Boolean, as is done for several other entries in options above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well I can use options in goto_symext but not in statet (unless I pass it there somehow).

@@ -241,9 +217,10 @@ void goto_symex_statet::assignment(
// the type might need renaming
rename(lhs.type(), l1_identifier, ns);
lhs.update_type();
assert_l1_renaming(lhs);
const validation_modet vm = global_validation_mode;
DATA_CHECK(!check_renaming_l1(lhs), "lhs renaming failed on l1");
Copy link
Collaborator

Choose a reason for hiding this comment

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

What I'd do here is something along the lines of !validation_enabled || !check_renaming_l1(lhs) to avoid changing the validation_modet enum.

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 reverted the new validation mode. I'm not sure if you're suggesting not to use DATA_CHECK at all and just call the regular invariants, or not. Have a look at the new version.

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.

Many thanks for the update!

@@ -524,7 +524,7 @@ class goto_symext
{
target.validate(ns, vm);
}
validation_modet global_validation_mode;
bool run_validation_checks;
Copy link
Collaborator

Choose a reason for hiding this comment

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

With the exception that I'd place this textually next to the other Boolean variables that store options, yes, this is how I thought it could be done.

if(run_validation_checks)
{
const validation_modet vm = local_validation_mode;
DATA_CHECK(!check_renaming_l1(lhs), "lhs renaming failed on l1");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hopefully that pain will go away soon when DATA_CHECK takes three arguments...

@@ -301,7 +301,7 @@ void goto_symext::symex_from_entry_point_of(

statet state;

state.global_validation_mode = global_validation_mode;
state.run_validation_checks = run_validation_checks;
Copy link
Collaborator

Choose a reason for hiding this comment

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

One future day we will actually have a proper constructor I suppose...

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: 77868dc).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91655999

@xbauch xbauch force-pushed the feature/ssa_validate branch from 77868dc to 6bc7648 Compare November 16, 2018 16:47
@xbauch
Copy link
Contributor Author

xbauch commented Nov 16, 2018

@tautschnig I've moved the Boolean flag to the previous ones and squashed the commits.

@xbauch xbauch force-pushed the feature/ssa_validate branch from 6bc7648 to 242655b Compare November 16, 2018 16:56
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: 242655b).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91697460

@xbauch xbauch assigned tautschnig and unassigned xbauch Nov 19, 2018
@chrisr-diffblue chrisr-diffblue changed the title Well-formedness checking of SSA equation Well-formedness checking of SSA equation [depends on #3480] Nov 29, 2018
Copy link
Contributor

@chrisr-diffblue chrisr-diffblue left a comment

Choose a reason for hiding this comment

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

LGTM, but would be good to rebase on top of #3480 and make the implicit parameter to DATA_CHECK be explicit.

assert_l1_renaming(lhs);

#if 0
const validation_modet local_validation_mode = validation_modet::INVARIANT;
Copy link
Contributor

Choose a reason for hiding this comment

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

If the validation mode is hardcoded to validation_modet::INVARIANT we could also use DATA_INVARIANT() directly instead. I think when using DATA_CHECK() the mode should be truly configurable.

{
caught = true;
}
REQUIRE(caught);
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 catch supports REQUIRE_THROWS_* macros to check that a particular exception is thrown.

danpoe and others added 2 commits November 30, 2018 08:25
Follows the diffblue#3123 skeleton with additional checks in SSA_stept. Adds a condition
such that renaming checks are only run with the validate option.
@xbauch xbauch force-pushed the feature/ssa_validate branch from 242655b to eb0b86b Compare November 30, 2018 10:55
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: eb0b86b).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/93144445

tautschnig added a commit that referenced this pull request Dec 1, 2018
…plicit-argument

Make validation mode parameter explicit in DATA_CHECK macros [blocks #3287]
@tautschnig tautschnig merged commit a6e0660 into diffblue:develop Dec 1, 2018
@xbauch xbauch deleted the feature/ssa_validate branch December 4, 2018 08:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants