Skip to content

Add conversion of overflow expressions into terms for the new incremental SMT support #6736

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 6 commits into from
Mar 23, 2022

Conversation

thomasspriggs
Copy link
Contributor

@thomasspriggs thomasspriggs commented Mar 18, 2022

This PR adds conversion of overflow expressions into terms for the new incremental SMT support.

  • 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.
  • 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).
  • 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.

@thomasspriggs thomasspriggs self-assigned this Mar 18, 2022
@codecov
Copy link

codecov bot commented Mar 18, 2022

Codecov Report

Merging #6736 (efd4635) into develop (c0f179c) will increase coverage by 0.02%.
The diff coverage is 86.32%.

@@             Coverage Diff             @@
##           develop    #6736      +/-   ##
===========================================
+ Coverage    76.87%   76.89%   +0.02%     
===========================================
  Files         1590     1590              
  Lines       183887   183974      +87     
===========================================
+ Hits        141364   141472     +108     
+ Misses       42523    42502      -21     
Impacted Files Coverage Δ
src/ansi-c/goto_check_c.cpp 91.47% <ø> (-0.15%) ⬇️
...c/solvers/smt2_incremental/convert_expr_to_smt.cpp 72.09% <79.48%> (+3.07%) ⬆️
src/goto-programs/builtin_functions.cpp 58.35% <100.00%> (+1.48%) ⬆️
src/util/pointer_expr.h 80.68% <100.00%> (ø)
src/util/simplify_expr_int.cpp 85.59% <100.00%> (ø)
src/util/std_expr.h 93.66% <0.00%> (+0.18%) ⬆️
src/util/bitvector_expr.h 97.28% <0.00%> (+0.54%) ⬆️
src/ansi-c/expr2c.cpp 67.36% <0.00%> (+0.74%) ⬆️
... and 1 more

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 4996426...efd4635. Read the comment docs.

@@ -735,6 +735,9 @@ class binary_overflow_exprt : public binary_predicate_exprt
{
check(expr, vm);
}

protected:
using binary_predicate_exprt::binary_predicate_exprt;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why did this turn out to be necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Strictly speaking it isn't. I could have reused the existing constructor of binary_overflow_exprt, in the constructors of the new sub-classes. This would have required specifying the kind as "plus" rather than ID_overflow_plus for example. So the constructor would have been converting c-string -> irep_idt -> std::string -> string concatenation -> irep_idt. The way I have implemented this uses the end result irep_idt directly, which saves the aforementioned conversions and makes it easier for readers of the sub-class to work out what the constructor sets the id to.

Note that constructors of sub-classes need to be able to explicitly construct their base classes if no default constructor is available and that even public constructors are not available for the construction of derived classes by default. Adding using binary_predicate_exprt::binary_predicate_exprt; allows me to use the constructor of binary_predicate_exprt to construct binary_overflow_exprt, without writing a whole constructor just to forward its arguments onto the base constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The approach I outlined here doesn't actually work, due to the constructor of binary_overflow_exprt hiding the constructor of binary_predicate_exprt. This has been bug fixed in the separated PR - #6744

{
return base.id() == ID_overflow_shl;
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thank you for adding these. But then these are missing some unary_minus_overflow_exprt (which is a unary_overflow_exprt).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank-you for the reminder. This could do with adding for completeness. However I have found that C examples with unary minus can be handled by cbmc being run with the new --incremental-smt2-solver argument, without supporting them in the new decision procedure, due to the checks being expressed in terms of more fundamental bit vector expressions in goto_check_c -

else if(expr.id() == ID_unary_minus)

As I read the code in goto_check_c and the code in the decision procedure, it seems that the implementation of the overflow checks is split / duplicated between these two different places. Do you know if there are any plans to change how this is structured?

Copy link
Contributor

@NlightNFotis NlightNFotis left a comment

Choose a reason for hiding this comment

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

Some questions.

Copy link
Contributor

@NlightNFotis NlightNFotis 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 to me.

This will require a rebase on top of develop, as it seems to contain an extraneous commit (the first one).

I'm happy for this to go in as is, and for unit/further regression tests to come later.

@thomasspriggs thomasspriggs marked this pull request as ready for review March 23, 2022 11:47
Copy link
Contributor

@TGWDB TGWDB left a comment

Choose a reason for hiding this comment

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

The documentation is nice when it's there. Not blocking, but it might be nice to have the log/explanation there for all of the overflow check logic.

@thomasspriggs thomasspriggs merged commit 629d029 into diffblue:develop Mar 23, 2022
@thomasspriggs
Copy link
Contributor Author

The documentation is nice when it's there. Not blocking, but it might be nice to have the log/explanation there for all of the overflow check logic.

Noted. I think this is just missing for the multiply operation. The other places should either be commented already, or fairly self explanatory.

@TGWDB
Copy link
Contributor

TGWDB commented Mar 24, 2022

The documentation is nice when it's there. Not blocking, but it might be nice to have the log/explanation there for all of the overflow check logic.

Noted. I think this is just missing for the multiply operation. The other places should either be commented already, or fairly self explanatory.

I found the codes ones ok to work out, but slower and a bit harder than the ones with nice comments as well as code.

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.

4 participants