-
-
Notifications
You must be signed in to change notification settings - Fork 748
Fix undefined behavior of BitsSet.popFront() upon aggressive optimization #4509
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
Conversation
|
Apparently this breaks on DMD's 32 bit targets. Seems valid at first glance, though, and it seems like there should be no way this causes a segfault?! |
|
Weird errors. :( |
|
Don't you need to increment |
|
Why? I thought when popFront leaves the range empty, front() can return garbage? |
|
I'm just looking at it from a perspective of having identical behavior as before. |
|
You still have a call to |
That would be |
|
Yeah, you are right. |
Nice!! thanks. |
|
Now that value cannot be 0 for the |
a166c9b to
d16cc66
Compare
|
@schveiguy updated! |
|
Well, LGTM. Let's hope it passes the 32-bit checkers. |
std/bitmanip.d
Outdated
| { | ||
| import core.bitop : bsf; | ||
| uint trailingZerosCount = bsf(_value); | ||
| // Because _value is non-zero, trailingZerosCount < sizeof(T)*8. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that you are using bsf, this comment seems rather out-of-place (bsf would have been undefined anyway). I'd say the above one is enough. And I liked the early-return version better.
|
@WalterBright @yebblies @MartinNowak: Any ideas about the 32 bit failures? Unless we are all missing something, this seems to be a misoptimization, ironically triggered by a fix to illegal code. |
d16cc66 to
d24f663
Compare
…aggressive optimization. The bug is triggered by the `assert(bitsSet(1).equal([0]));` unittest already present, with LDC+aggressive inlining and optimization.
d24f663 to
46f0d65
Compare
Current coverage is 88.67% (diff: 100%)@@ master #4509 diff @@
==========================================
Files 121 121
Lines 73827 73810 -17
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
- Hits 65471 65454 -17
Misses 8356 8356
Partials 0 0
|
|
(rebased) |
Looks like a DMD code gen bug, I've reduced & filed it here: https://issues.dlang.org/show_bug.cgi?id=17034 |
|
The fix was merged and seems to have worked. Time to move this forward? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix was merged and seems to have worked.
Thanks a lot @WalterWaldron!
The changes look good to me.
Same here -> +1
As the fix was merged, it passes all CI checks, the change is fairly simply and nobody objected in the last seven days - I will go ahead and merge it, s.t. it will be part of the upcoming 2.073 release ;-) |
A right-shift of a number of bits >= type's bits is invalid.
In this case, BitsSet was doing a
>>>=32on anint, leading to undefined behavior with aggressive optimizations in LDC. The solution in this PR is stopping further processing when the range has become empty by the popFront() call.The bug is triggered by the
assert(bitsSet(1).equal([0]));unittest already present, with LDC+aggressive inlining and optimization.