Skip to content

Fix spurious overflow counter examples. (#558)#647

Merged
celinval merged 5 commits intomodel-checking:mainfrom
celinval:issue-558
Nov 23, 2021
Merged

Fix spurious overflow counter examples. (#558)#647
celinval merged 5 commits intomodel-checking:mainfrom
celinval:issue-558

Conversation

@celinval
Copy link
Contributor

@celinval celinval commented Nov 15, 2021

Description of changes:

RMC was treating all arithmetic operations as non-wrapping which was triggering a lot of spurious counter examples. Instead of relying on cbmc generated overflow checks, we are not explicitly encoding checks for non-wrapping operations.

Resolved issues:

Resolves #558

Call-outs:

I created #646 to track implementing more checks that we currently don't support. Except for shift left and division by 0, I believe CBMC doesn't have any mechanism to check them.

Testing:

  • How is this change tested?

I created a bunch of new tests.

  • Is this a refactor change?

I guess.

Checklist

  • Each commit message has a non-empty body, explaining why the change was made
  • Methods or procedures are documented
  • Regression or unit tests are included, or existing tests cover the modified code
  • My PR is restricted to a single feature or bugfix

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

@celinval celinval requested a review from a team as a code owner November 15, 2021 22:48
Copy link
Contributor

@zhassan-aws zhassan-aws Nov 16, 2021

Choose a reason for hiding this comment

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

Do the cases here (e.g. LHS is a pointer and RHS is an integer) apply to overflow addition/subtraction/multiplication? EDIT: I see now that some of those cases apply to intrinsics.

Copy link
Contributor

Choose a reason for hiding this comment

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

The argument types have to remain the same for each operation (i.e., OverflowMinus goes with Minus).

Copy link
Contributor Author

@celinval celinval Nov 16, 2021

Choose a reason for hiding this comment

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

Makes sense. Do you know why the minus has different requirements?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, minus allows both operands to be pointers because it is valid to compute offsets between them. This does not apply to plus because adding two pointers will likely result in another pointer to who-knows-where.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I hadn't thought about that. Good point.

I removed the vector from the list since it doesn't look like CBMC overflow operation actually accepts C arrays.While trying to reproduce the issue to file a bug report, I noticed that CBMC was printing the following warning:

warning: ignoring overflow-*
  * type: bool
  0: array
      * type: array
          * #source_location: nil
          * size: constant
              * type: signedbv
                  * width: 64
                  * #c_type: signed_long_int
              * value: 2
          0: signedbv
              * width: 8
      0: constant
          * type: signedbv
              * width: 8
          * value: 0
      1: constant
          * type: signedbv
              * width: 8
          * value: 0
  1: array
      * type: array
          * #source_location: nil
          * size: constant
              * type: signedbv
                  * width: 64
                  * #c_type: signed_long_int
              * value: 2
          0: signedbv
              * width: 8
      0: constant
          * type: signedbv
              * width: 8
          * value: 0
      1: constant
          * type: signedbv
              * width: 8
          * value: 0

Copy link
Contributor

@zhassan-aws zhassan-aws left a comment

Choose a reason for hiding this comment

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

Looks great! The new tests are very good!

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you want to add sum1 >= b as well?

Copy link
Contributor

@adpaco-aws adpaco-aws left a comment

Choose a reason for hiding this comment

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

The changes here heavily rely on -C overflow-checks=on. Can we add a check to our back-end to ensure the flag is always set?

Copy link
Contributor

Choose a reason for hiding this comment

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

The argument types have to remain the same for each operation (i.e., OverflowMinus goes with Minus).

Comment on lines 183 to 185
Copy link
Contributor

Choose a reason for hiding this comment

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

A few lines below there is codegen_intrinsic_binop which does the same thing. Why did you add this?

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 was trying to make it explicit that this is a wrapping operation. To avoid others to inadvertently using the wrong operation in the future.

I could modify this to just call the binop one or remove this. Any preference?

@celinval
Copy link
Contributor Author

The changes here heavily rely on -C overflow-checks=on. Can we add a check to our back-end to ensure the flag is always set?

Should we allow users to turn them off though? What if I add a check with a warning if the flag is off?

Copy link
Contributor

@adpaco-aws adpaco-aws left a comment

Choose a reason for hiding this comment

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

Looking good! Of course, we can change the check in the near future to support other use cases, but I do not feel comfortable with our codegen depending on this flag and not requiring it.

@tedinski
Copy link
Contributor

Doesn't this mean we no longer spot overflows in unsafe code?

@celinval
Copy link
Contributor Author

Doesn't this mean we no longer spot overflows in unsafe code?

That's a great question! I should definitely add test cases for that.

We are still checking for overflow in unsafe code. Regular arithmetic operations are always checked no matter where they show up in the code.

@celinval
Copy link
Contributor Author

This should be check_mul

I wonder how this test even passed. o.O

@adpaco-aws
Copy link
Contributor

I wonder how this test even passed. o.O

Probably because CBMC is not finding the function to verify and that is understood as a verification failure.

@celinval celinval merged commit b04b7a9 into model-checking:main Nov 23, 2021
@celinval celinval deleted the issue-558 branch November 23, 2021 19:18
@adpaco-aws adpaco-aws mentioned this pull request Apr 19, 2022
tedinski pushed a commit to tedinski/rmc that referenced this pull request Apr 26, 2022
…hecking#647)

We cannot easily specify which arithmetic operations are wrapping ones to CBMC. Thus, CBMC was generating overflow checks for wrapping operations which were generating spurious failures. This change disables some of those CBMC checks. We replace them by using rustc overflow checks for regular operations and by explicitly adding checks to unchecked operations.
tedinski pushed a commit that referenced this pull request Apr 27, 2022
We cannot easily specify which arithmetic operations are wrapping ones to CBMC. Thus, CBMC was generating overflow checks for wrapping operations which were generating spurious failures. This change disables some of those CBMC checks. We replace them by using rustc overflow checks for regular operations and by explicitly adding checks to unchecked operations.
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.

Spurious overflow failures with Result/Error types

4 participants