Skip to content

Change shift operators to throw on undefined behavior instead of assert #64

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

dcleblanc
Copy link
Owner

The class had assertions for UB on shift, turn the asserts into exceptions.

Copy link

@bbannier bbannier left a comment

Choose a reason for hiding this comment

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

Thanks for this, this does fix my original issue.

Just wondering, any invalid bitshifts caught here would be UB, not (possibly defined) overflow, but SafeInt only exposes overflow and div by zero errors. Does it make sense to introduce dedicated handlers for UB via a breaking change or is that too hard to disentagle cleanly anyway?

@@ -324,7 +324,7 @@ The shift operators have the following signatures:
SafeInt< U, E > operator >>( U lhs, SafeInt< T, E > bits )

Note:
Shift operations where the right argument is larger than the number of bits in the left argument type minus 1 is implementation-defined behavior. SafeInt will attempt to help you avoid this by causing an assert in debug builds. If you prefer to have a stronger reaction, create a custom SAFEINT_ASSERT that throws or causes a fault in both debug and release builds. Shifting by a negative bit count also doesn't make sense, and is also trapped.
Shift operations where the right argument is larger than the number of bits in the left argument type minus 1 is implementation-defined behavior. Undefined behavior, such as shifting by a negative count or more bits than the type has will throw an exception.
Copy link

@bbannier bbannier Aug 7, 2024

Choose a reason for hiding this comment

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

NB: I had missed that SAFEINT_ASSERT was a customization point which might have been a way to get around this.

Even with that info I believe having shift operations throw would still be preferable since that can provide more context (e.g., that we ran into an overflow instead of some other assertion failure).

Copy link
Owner Author

Choose a reason for hiding this comment

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

So it's technically implementation defined, not UB, which is slightly different. With UB, the compiler can upload your source to the Internet. With implementation defined, it has to do something, compiler vendor decides what.

I think treating it as an overflow is reasonable.

And yes, prior to this you could have made a different ShiftAssert and caused the same as with this fix.

@bbannier
Copy link

@dcleblanc, is this something you would be willing to merge?

bbannier added a commit to zeek/spicy that referenced this pull request Oct 17, 2024
rsmmr added a commit to zeek/spicy that referenced this pull request Dec 3, 2024
We now use a fork of `SafeInt` that includes
dcleblanc/SafeInt#64 (as well as general bump
to upstream `master`).
rsmmr added a commit to zeek/spicy that referenced this pull request Dec 6, 2024
We now use a fork of `SafeInt` that includes
dcleblanc/SafeInt#64 (as well as general bump
to upstream `master`).
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.

2 participants