Skip to content
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

-ftrapv reports signed integer overflows on left shift #31

Closed
nmathewson opened this issue Oct 31, 2014 · 7 comments
Closed

-ftrapv reports signed integer overflows on left shift #31

nmathewson opened this issue Oct 31, 2014 · 7 comments

Comments

Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
@nmathewson
Copy link

@nmathewson nmathewson commented Oct 31, 2014

Apparently, C thinks that a left shift of a negative number is undefined behavior. But the donna code does this.

A volunteer contributor to Tor, named "teor", has sent us a patch to fix this issue. We'd like it to go upstream before we merge it, though. You can see the ticket at https://trac.torproject.org/projects/tor/ticket/13538 . This code will need a bit of hacking to go into donna. I'm making this issue as a placeholder.

@agl
Copy link
Owner

@agl agl commented Nov 9, 2014

From looking at teor2345/tor@ced74e0, it seems very ugly -- I don't want to merge that I'm afraid.

@agl agl closed this Nov 9, 2014
@nmathewson
Copy link
Author

@nmathewson nmathewson commented Nov 17, 2014

Okay. Would you be amenable in principle to some other approach to avoid left-shifting negative numbers? It is technically undefined, if I'm researching this properly.

@agl
Copy link
Owner

@agl agl commented Nov 17, 2014

Yes, it's technically undefined behaviour:

2 The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2^E2, reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1 × 2^E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.

However, it's the result of trying to support non-two's complement machines. That may have made sense in the 1970's but I'm very dubious that we should be paying the cost to support them now. (I'm not sure if they still even exist.)

Rather I'm seeing whether there's support in the standards group for defining this behaviour.

@nmathewson
Copy link
Author

@nmathewson nmathewson commented Dec 3, 2014

Any updates here?

@zackw
Copy link

@zackw zackw commented Oct 29, 2015

Even if the C committee makes this defined -- and I strongly suspect they won't -- it will be decades before C compilers are all updated to acknowledge the change.

The patch should be merged.

@thestinger
Copy link

@thestinger thestinger commented Oct 30, 2015

@agl: You should at least add -fwrapv to CFLAGS as the Linux kernel does to get well-defined two's complement wrapping. Clang and GCC really do break code with signed overflow unless -fwrapv is passed.

@richfelker
Copy link

@richfelker richfelker commented Nov 17, 2015

The right way to "left shift a possibly negative number" is to simply write x*(1<<n). It has the exact semantics you want but without the undefined behavior (assuming no overflow). If you also want well-defined behavior on overflow without depending on non-portable compiler extensions you need to convert to an unsigned type and back.

mkj added a commit to mkj/dropbear that referenced this issue Jun 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment