Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Add length, lower and upper bounds to RangeError/_d_arraybounds #2377

Closed
wants to merge 2 commits into from

Conversation

thewilsonator
Copy link
Contributor

No description provided.

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @thewilsonator! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the annotated coverage diff directly on GitHub with CodeCov's browser extension
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub fetch digger
dub run digger -- build "master + druntime#2377"

@thewilsonator
Copy link
Contributor Author

Ah, need to do phobos as well.

@thewilsonator thewilsonator force-pushed the fix_range_error branch 2 times, most recently from 1956414 to 3109d18 Compare November 27, 2018 05:14
@thewilsonator
Copy link
Contributor Author

thewilsonator commented Nov 27, 2018

Hmm, test is being compiled with -release which is suppressing the call to _d_array_bounds.
e: Darn, looks like the only way around this is to change the makefiles, urgh.

@jmdavis
Copy link
Member

jmdavis commented Nov 27, 2018

Hmm, test is being compiled with -release which is suppressing the call to _d_array_bounds.
e: Darn, looks like the only way around this is to change the makefiles, urgh.

Mark the unittest as @safe.

@thewilsonator
Copy link
Contributor Author

Thanks!

@thewilsonator
Copy link
Contributor Author

Hmm, nope: Error: can only catch class objects derived from Exception in @safe code, not core.exception.RangeError

@thewilsonator
Copy link
Contributor Author

Ahh, @safe lambdas work.

@jmdavis
Copy link
Member

jmdavis commented Nov 27, 2018

Hmm, nope: Error: can only catch class objects derived from Exception in @safe code, not core.exception.RangeError

That's nice. I wasn't expecting that to be the case, but it really should be.

Ahh, @safe lambdas work.

Yeah, if you can't make the whole thing @safe, then making the pieces you need @safe via lambdas should get around it. Either way, since -release should never be stripping out array bounds checking in @safe code, as long as the portions of the tests indexing arrays out-of-bounds are @safe, the checks should still be in place. If not, then it's a compiler bug.

@thewilsonator
Copy link
Contributor Author

This doubles as a nice test for that then.

@thewilsonator
Copy link
Contributor Author

(I've altered the testes to figure out what indices are passed to _d_arraybounds.)

@thewilsonator
Copy link
Contributor Author

core.exception.RangeError@src/core/exception.d(137): Range violation: indicies [6250512 .. 6250512] exceeds array length 6250512
Yeah that looks like garbage arguments.

src/core/exception.d Outdated Show resolved Hide resolved
src/core/exception.d Outdated Show resolved Hide resolved
@adamdruppe
Copy link
Contributor

I think you were over-zealous with the copy/paste of your print code rather than the arguments being garbage.

That length does seem a bit odd, but it being repeated is just it printing the same variable three times.

@thewilsonator
Copy link
Contributor Author

CircleCI reports its triple as x86_64-pc-linux-gnu.

}

void _d_arraybounds(string file, uint line)
void _d_arraybounds(string file, uint line, size_t lower, size_t upper, size_t length)
Copy link
Member

Choose a reason for hiding this comment

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

Rather than changing the signatures of the public extern C interface, new functions should be introduced.

Copy link
Member

Choose a reason for hiding this comment

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

Agreed. Then we don't have to risk merging this + the DMD change at the same time - this could be merged first, then the DMD patch can be merged if it passes CI.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For reference the DMD patch is already in, hence why I want to get this in. Also as noted by Jacob, we don't guarantee binary compatibility across releases.

Copy link
Member

@ibuclaw ibuclaw Jan 10, 2019

Choose a reason for hiding this comment

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

See _aaGet, _aaGetX, _aaGetY for examples of doing this in the past. Infact pick any function that ends in X (_d_arrayliteralTX)

Even _d_arrayboundsp was a new name given to replace _d_arrayboundsm. :-)

Copy link
Member

Choose a reason for hiding this comment

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

But what's the point of doing so and creating more legacy cruft if we don't we don't guarantee binary compatibility across releases anyhow?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Call parameter stack layout: adding args to the end doesn't affect previous ones. I.e. passing too many will ignore the later ones, whereas passing too few will lead to garbage/corruption.

Copy link
Member

Choose a reason for hiding this comment

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

Great, so that means it works on x86, x86_64, and ... ? I don't think this calling convention is universal, is it?

Copy link
Member

Choose a reason for hiding this comment

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

x86 is the only target that pushes arguments in reverse. All others are left to right.

I have an ARM and Aarch64 server that I can run a test on. Regressions on those targets could warrant a revert... Did the druntime changes end up in a release?

Copy link
Member

Choose a reason for hiding this comment

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

Assuming that it's a dmd backend change only though, it's not so critical. If array bounds checks were being generated by the frontend, then it's another matter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is a backend thing.

@jacob-carlborg
Copy link
Contributor

CircleCI reports its triple as x86_64-pc-linux-gnu.

Right, not sure what I was thinking.

@thewilsonator
Copy link
Contributor Author

@ibuclaw signature of public functions is now compatible with default arguments. The functions you commented in are compiler generated.

@ibuclaw
Copy link
Member

ibuclaw commented Jan 7, 2019

They will still silently break with applications linked to previous libraries. Just questioning whether this warrants a backwards incompatible ABI version bump.

@jacob-carlborg
Copy link
Contributor

We don't guarantee any ABI compatibility as far as I know.

@thewilsonator
Copy link
Contributor Author

Hey, it passes on CircleCI! Yay! I've no idea why that was failing before.

src/core/exception.d Outdated Show resolved Hide resolved
src/core/exception.d Outdated Show resolved Hide resolved
src/core/exception.d Outdated Show resolved Hide resolved
changelog/range-error.dd Outdated Show resolved Hide resolved
changelog/range-error.dd Show resolved Hide resolved
src/core/exception.d Outdated Show resolved Hide resolved
src/core/exception.d Outdated Show resolved Hide resolved
}
catch (Throwable)
{
// ignore more errors
Copy link
Member

Choose a reason for hiding this comment

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

src/core/exception.d Show resolved Hide resolved
}

void _d_arraybounds(string file, uint line)
void _d_arraybounds(string file, uint line, size_t lower, size_t upper, size_t length)
Copy link
Member

Choose a reason for hiding this comment

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

Agreed. Then we don't have to risk merging this + the DMD change at the same time - this could be merged first, then the DMD patch can be merged if it passes CI.

@CyberShadow
Copy link
Member

BTW, how did the DMD PR get merged without this one? Wouldn't the change in function signatures break the DMD/Druntime ABI?

@thewilsonator
Copy link
Contributor Author

Because is passed the CI. Arguments added to the end of the parameter list don't collide with ones earlier in the list.

Copy link
Member

@CyberShadow CyberShadow left a comment

Choose a reason for hiding this comment

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

Looking at this again - the if (upper) and if (lower) checks do not look good and generate inconsistent and potentially misleading messages.

For example:

auto a = (new int[0])[1]; // Range violation: index [1] exceeds array length 0
auto b = (new int[0])[0]; // Range violation

auto c = (new int[0])[1..1]; // Range violation: indicies [1 .. 1] exceeds array length 0
auto d = (new int[0])[0..1]; // Range violation: index [1] exceeds array length 0
auto e = (new int[0])[-1..0]; // Range violation

The d one in particular is outright misleading, we are not accessing index 1, only slicing up to it.

I think we should avoid misleading users, so that should probably need to be fixed before this is merged. What do you think?

@CyberShadow
Copy link
Member

Suggested fix:

  • Introduce new C functions as suggested by @ibuclaw
  • Store separately whether we have zero (old API), one (index) or two (slice) indices
  • Format accordingly to number of indices we have

@thewilsonator
Copy link
Contributor Author

a,b,c and e are edge cases, I will fix those soon.

d while potentially misleading, cross-referencing the line number will show a slice.

@CyberShadow
Copy link
Member

a,b,c and e are edge cases, I will fix those soon.

Not sure what you mean by fix - a and c look correct, they are there for comparison.

I don't think there's a reasonable way to fix this in general without additional state / transmitted information. There are no free bits to hold information on whether the indices are actually indices, and the two indices don't necessarily have a relation to each other.

d while potentially misleading, cross-referencing the line number will show a slice.

That doesn't sound great. It's the worst case, and it might not be the only indexing operation on the line.

@thewilsonator
Copy link
Contributor Author

Not sure what you mean by fix - a and c look correct, they are there for comparison.

My bad about a, the rest were wrong and I assumed that was too. c, unless you mispasted, is missing the the length of the array at the end.

@CyberShadow
Copy link
Member

Yes, that was a mispaste, sorry.

@dkorpel
Copy link
Contributor

dkorpel commented Mar 31, 2021

I would love to get this in. Are you still going to work on this @thewilsonator?

@thewilsonator
Copy link
Contributor Author

not with any sense of urgency.

@12345swordy
Copy link
Contributor

How much left is needed for this to be done?

@dlang-bot dlang-bot added Needs Rebase needs a `git rebase` performed stalled labels May 27, 2021
@Geod24 Geod24 added the Phantom Zone Has value/information for future work, but closed for now label Jun 2, 2021
@Geod24
Copy link
Member

Geod24 commented Jun 2, 2021

Closing for lack of activity (and to clean up upstream branches). The enhancement would be amazing to have, though.

@Geod24 Geod24 closed this Jun 2, 2021
@Geod24 Geod24 deleted the fix_range_error branch June 2, 2021 03:43
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Needs Rebase needs a `git rebase` performed Phantom Zone Has value/information for future work, but closed for now stalled
Projects
None yet