dmd
dmd copied to clipboard
Add `CastExp.toLvalue` dip1000 error if implicit pointer conversion would fail
From https://dlang.org/spec/expression.html#.define-lvalue
The following expressions, and no others, are called lvalue expressions or lvalues ... cast(U) expressions applied to lvalues of type T when T* is implicitly convertible to U*; cast() and cast(qualifier list) when applied to an lvalue.
The first rule was not enforced by dmd. The second rule contradicts the point of the first rule. It ~~should~~ perhaps could be updated to work in the same way.
Fixes Issue 23530 - casting immutable away allowed in safe.
Edit: Changed to dip1000 error rather than obsolete warning.
Thanks for your pull request and interest in making D better, @ntrel! 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:andReturns:)
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 |
|---|---|---|---|
| ✓ | 23530 | critical | casting immutable away allowed in safe |
⚠️⚠️⚠️ Warnings ⚠️⚠️⚠️
- Regression or critical bug fixes should always target the
stablebranch. Learn more about rebasing tostableor the D release process.
To target stable perform these two steps:
- Rebase your branch to
upstream/stable:
git rebase --onto upstream/stable upstream/master
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#15597"
This makes _dupCtfe get inferred @system even though there's no cast:
foreach (ref e; a)
res ~= e; // offending line
Not sure how to avoid that. It lowers to:
for (; __key3 < __r2.length; __key3 += 1LU)
{
const ref const(S) e = __r2[__key3];
(ref S __appendtmp4 = e;) , (_d_arrayappendcTX(res, 1LU) , res[res.length - 1LU] = __appendtmp4 , res);
}
But still there's no cast and _d_arrayappendcTX is @trusted anyway.
I'm not sure where the cast expression comes from when calling _dupCtfe:
foreach (ref e; a)
res ~= e; // offending line
I tried to work around that by ignoring any casts in functions being interpreted at compile-time, but I'm clearly not detecting that correctly. Using SCOPE.ctfeBlock doesn't work either.
Closing in favour of https://github.com/dlang/dmd/pull/16315#issuecomment-2016931657