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

fix issue 23565 - Allow the use of $ as index on .ptr expressions #14716

Closed
wants to merge 1 commit into from
Closed

fix issue 23565 - Allow the use of $ as index on .ptr expressions #14716

wants to merge 1 commit into from

Conversation

ghost
Copy link

@ghost ghost commented Dec 19, 2022

We can use .ptr in slice and indexes expressions to bypass bounds verification but then we loose the opportunity to use $ in the expression that give the subscripts, even if an array is present and hence a .length is possible.

This commit fix the problem as long as the .ptr LHS is a (optionally dotted) variable

The implementation is based on a front-end lowering as the existing system was not designed for this case (it finalizes the substitution in the mid-end function resolveLengthVar())

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @SixthDot! 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 coverage diff by visiting the details link of the codecov check)
  • 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

Auto-close Bugzilla Severity Description
23565 enhancement Change `$` semantics so that it works with `.ptr` too

Testing this PR locally

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

dub run digger -- build "master + dmd#14716"

We can use `.ptr` in slice and indexes expressions to bypass bounds verification
but then we loose the opportunity to use `$` in the expression that give the subscripts,
even if an array and hence a `.length` is possible.

This commit fix the problem as long as the `.ptr` LHS is a (optionally dotted) variable

The implementation is based on a front-end lowering as the existing
system was not designed for this case (it finalize the substitution in
the mid-end function `resolveLengthVar()`)
@thewilsonator thewilsonator added Review:Needs Changelog A changelog entry needs to be added to /changelog Review:Needs Spec PR A PR updating the language specification needs to be submitted to dlang.org labels Dec 19, 2022
@ghost
Copy link
Author

ghost commented Dec 19, 2022

@thewilsonator, a changelog entry is there

@UplinkCoder
Copy link
Member

How can this work ?
I see you are pushing a scope for resolution but you aren't popping it.

I am sure a more complicated example would fail.

if (auto tp = ce.type.isTypePointer())
{
const cty = ce.e1.type.ty;
const cop = ce.e1.op;
Copy link
Member

Choose a reason for hiding this comment

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

why cop and cty ?
because of the const?
generally we don't use Hungarian notation.

a.ptr[0 .. $] = [1,2];
assert(a == [1,2]);

s.a.ptr[0 .. $] = [1,2];
Copy link
Member

Choose a reason for hiding this comment

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

You use the same arrays with the same lengths.
Use another array with different length.

Then use a struct where opDollar is overloaded.
The current tests can easily hide unwanted interaction.

@ghost
Copy link
Author

ghost commented Dec 19, 2022

How can this work ?
I see you are pushing a scope for resolution but you aren't popping it.

I am sure a more complicated example would fail.

No. Check a few lines before. The scope sc is saved in scx and restored to that value later if sc has changed during the sema of the index(es)

@@ -13790,3 +13796,23 @@ Expression toBoolean(Expression exp, Scope* sc)
return e;
}
}

/* Push the necessary scope to solve `$` in `e1.ptr[$]` or `e1.ptr[0 .. $]` */
Copy link
Member

Choose a reason for hiding this comment

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

solve -> resolve.

@Herringway
Copy link
Contributor

This appears to have the potential to break existing code. Consider this currently-legal example:

    auto a = [1,2,3,4,5,6,0];
    auto b = [0,1,2,3,4,5,6,7];
    writeln(b[a.ptr[$ - 2]]);

This is legal code today, and it prints 0. With this change, will it print 0 or 6?

Furthermore, why is .ptr treated specially here? Why does this not extend to other properties, or even UFCS'd functions? And what of array-like structs that have both a .ptr and opDollar? do they get to take advantage of this feature?

@atilaneves
Copy link
Contributor

I don't understand the point of this PR. I know what it does, but I don't know why. It shouldn't be common to do this, and the "to bypass bounds checks" is an interesting phrase to use here.

Indexing into a pointer that came from a slice/dynamic array is, at the very least, weird.

@maxhaton
Copy link
Member

I don't understand the point of this PR. I know what it does, but I don't know why. It shouldn't be common to do this, and the "to bypass bounds checks" is an interesting phrase to use here.

Indexing into a pointer that came from a slice/dynamic array is, at the very least, weird.

If nothing else it makes it more plastic to use .ptr in existing code (primarily for guaranteeing there being no bounds check locally)

@ghost
Copy link
Author

ghost commented Dec 20, 2022

As per @Herringway comment, this is actually a breaking change in nested array expressions.

@ghost ghost closed this Dec 20, 2022
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Review:Needs Changelog A changelog entry needs to be added to /changelog Review:Needs Spec PR A PR updating the language specification needs to be submitted to dlang.org Review:Walter Bright Severity:Enhancement Severity:New Language Feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants