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 Bugzilla 24434 - Casting away const with cast() is not a @safe lv… #16315

Merged
merged 10 commits into from
Apr 28, 2024

Conversation

ntrel
Copy link
Contributor

@ntrel ntrel commented Mar 16, 2024

…alue

@dlang-bot
Copy link
Contributor

dlang-bot commented Mar 16, 2024

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: 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
23530 critical casting immutable away allowed in safe
24434 normal Casting away const with cast() should not produce an lvalue

⚠️⚠️⚠️ Warnings ⚠️⚠️⚠️

To target stable perform these two steps:

  1. Rebase your branch to upstream/stable:
git rebase --onto upstream/stable upstream/master
  1. Change the base branch of your PR to stable

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#16315"

@ntrel ntrel marked this pull request as draft March 16, 2024 12:36
@ntrel
Copy link
Contributor Author

ntrel commented Mar 16, 2024

src/core/internal/array/duplication.d(38):        cast from `ArrElem` to `immutable(ArrElem)` cannot be used as an lvalue in @safe code
src/object.d(3871):        `object.idup!(ArrElem).idup` is declared here

That is triggered in _dupCtfe:

        U[] res;
        foreach (ref e; a)
            res ~= e; // this line

So I'm not sure how to fix that. Also the error should maybe be a deprecation.

@dkorpel
Copy link
Contributor

dkorpel commented Mar 16, 2024

Also the error should maybe be a deprecation.

Yes, before we have editions, you can use setUnsafePreview(FeatureState.default_, ... for that

ntrel added a commit to ntrel/phobos that referenced this pull request Mar 16, 2024
See dlang/dmd#16315

With that pull, using a type qualifier cast is not @safe to use as an
lvalue.
dlang-bot pushed a commit to dlang/phobos that referenced this pull request Mar 16, 2024
See dlang/dmd#16315

With that pull, using a type qualifier cast is not @safe to use as an
lvalue.
@thewilsonator
Copy link
Contributor

../buildkite-ci-build/.dub/packages/libdparse/0.19.4/libdparse/src/dparse/lexer.d(158,23): Deprecation: cast from `const(string)` to `string` cannot be used as an lvalue in @safe code
../buildkite-ci-build/.dub/packages/libdparse/0.19.4/libdparse/src/dparse/parser.d(188,42): Error: template instance `dparse.parser.Parser.attachCommentFromSemicolon!(AliasDeclaration)` error instantiating
../dmd/generated/linux/release/64/dmd -conf= -I../dmd/druntime/import  -w -de -preview=dip1000 -preview=dtorfields -preview=fieldwise -m64 -fPIC -O -release -unittest -version=StdUnittest -c -ofgenerated/linux/release/64/unittest/std/format/package.o std/format/package.d
../buildkite-ci-build/.dub/packages/libdparse/0.19.4/libdparse/src/dparse/lexer.d(150,23): Deprecation: cast from `const(string)` to `string` cannot be used as an lvalue in @safe code
Error /buildkite/builds/geod24-main-1/dlang/dmd/dmd/generated/linux/release/64/dmd failed with exit code 1.

Looks like libdparse needs to be updated? (or not compiled with -de)

@RazvanN7
Copy link
Contributor

I find it icky that the fix is located in a function that is queried for finding the lvalueness of an expression. There is a function called isSafeCast and I think that's where the fix should be located.

On a different note: casting away a qualifier returns an lvalue irrespective of the fact if we are in safe code or not. I think that we should just consider banning casting away qualifiers in @safe code. That will put as to safety with regards to code such as this:

void main() @safe
{
    const int i = 2;
    cast()i = 3;
}

This currently compiles, and I don't think this patch solves this case (athough, IMO it should).

@ntrel
Copy link
Contributor Author

ntrel commented Mar 20, 2024

There is a function called isSafeCast and I think that's where the fix should be located.
...
I think that we should just consider banning casting away qualifiers in @safe code

@RazvanN7 isSafeCast doesn't know about lvalues. So I tried making even lvalue QualCast unsafe:

std/utf.d(3172): Deprecation: qualifier cast from `immutable(char)` to `char` not allowed in @safe code
...
std/math/algebraic.d(979):        which wouldn't be `@safe` because of:
std/math/algebraic.d(979):        qualifier cast from `const(ulong)` to `ulong` not allowed in @safe code

utf.d has lots of typeof(cast() ..., which still trigger the deprecation. I'm guessing there's some way of saying to ignore safety inside typeof, which would fix those.

The algebraic.d one is return cast() cast(T) ... in a private function that returns an rvalue. So things like this which are safe (when T is POD) will be broken if you deprecate/error for rvalues as well.

There is an advantage that this doesn't need the duplication.d change of this pull, which creates a copy instead of ref which is probably wrong.

I don't think this patch solves this case (athough, IMO it should).

It actually does detect that. I'll add it to the test later.

ntrel added a commit to ntrel/libdparse that referenced this pull request Mar 20, 2024
WebFreak001 pushed a commit to dlang-community/libdparse that referenced this pull request Mar 20, 2024
@ntrel
Copy link
Contributor Author

ntrel commented Mar 23, 2024

There is an advantage that this doesn't need the duplication.d change of this pull, which creates a copy instead of ref which is probably wrong.

I undid that change, it is not necessary now I'm doing the check for a qualifier cast correctly.

@ntrel
Copy link
Contributor Author

ntrel commented Mar 23, 2024

Now broken - somehow the mod field is 0/1 (for mutable/const in the test) as expected when CastExp is visited for semantic analysis, but then by the time toLvalue is called, the mod field has become 255, and I can't detect the qualifier cast anymore. Maybe the CastExp got replaced with another one, because nowhere modifies mod.

Fixes Bugzilla 23530 - casting immutable away allowed in safe.
@ntrel
Copy link
Contributor Author

ntrel commented Mar 24, 2024

As I can't detect a qualifier cast in toLvalue, I decided to also fix the non-qualifier unsafe lvalue cast bug too. I found the CatAssignExp semantic code that calls castTo for a safe append and added a workaround.

@ntrel
Copy link
Contributor Author

ntrel commented Mar 24, 2024

buildkite is failing on phobos because libdparse 0.19.4 doesn't have the upstream fix:

../buildkite-ci-build/.dub/packages/libdparse/0.19.4/libdparse/src/dparse/lexer.d(158,23): Deprecation: cast from `const(string)` to `string` cannot be used as an lvalue in @safe code
../buildkite-ci-build/.dub/packages/libdparse/0.19.4/libdparse/src/dparse/parser.d(188,42): Error: template instance `dparse.parser.Parser.attachCommentFromSemicolon!(AliasDeclaration)` error instantiating
../buildkite-ci-build/.dub/packages/libdparse/0.19.4/libdparse/src/dparse/lexer.d(150,23): Deprecation: cast from `const(string)` to `string` cannot be used as an lvalue in @safe code

@ntrel ntrel marked this pull request as ready for review March 24, 2024 21:35
@ntrel ntrel requested a review from ibuclaw as a code owner March 24, 2024 21:35
@ntrel
Copy link
Contributor Author

ntrel commented Mar 27, 2024

Ping. So does this mean we have to wait for libdparse to be released with the fix before this can be merged?

@RazvanN7
Copy link
Contributor

Yes, we need to fix libdparse, however, the fix seems trivial.

@ntrel
Copy link
Contributor Author

ntrel commented Mar 27, 2024

@RazvanN7 The fix is already merged: dlang-community/libdparse#514

Does the phobos buildkite test require libdparse to be the last released version?

MrcSnm pushed a commit to MrcSnm/phobos that referenced this pull request Mar 27, 2024
See dlang/dmd#16315

With that pull, using a type qualifier cast is not @safe to use as an
lvalue.
@thewilsonator
Copy link
Contributor

Does the phobos buildkite test require libdparse to be the last released version?

Currently it is testing against libdparse 0.19.4. The current release of libdparse is 0.23.2 released July 2023.
We will need to tag a new release and then update the version that we test against.

@RazvanN7
Copy link
Contributor

@ntrel Phobos seems to continue failing. Does this need a rebase?

@ntrel
Copy link
Contributor Author

ntrel commented Apr 27, 2024

@RazvanN7 There's been a libdparse v0.24.0 release with the fix but I'm not sure where the file is that specifies 0.19.4 for buildkite - @thewilsonator any idea?

@dkorpel
Copy link
Contributor

dkorpel commented Apr 27, 2024

I think it's dlang/tools#471, and dlang/dlang.org#3815 might also be necessary

@ntrel
Copy link
Contributor Author

ntrel commented Apr 28, 2024

buildkite now passing!

@thewilsonator thewilsonator merged commit e60bfd1 into dlang:master Apr 28, 2024
46 checks passed
@ntrel ntrel deleted the unsafe-qual-cast branch November 20, 2024 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants