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 21821 - Optimizer assumes immutables do not change, but the… #12424

Merged
merged 1 commit into from Feb 7, 2023

Conversation

WalterBright
Copy link
Member

…y can in @System code

Another problem unearthed by #12409

The fix is to tell the backend if a function is @safe

@WalterBright WalterBright added the Backend glue code, optimizer, code generation label Apr 12, 2021
@dlang-bot
Copy link
Contributor

dlang-bot commented Apr 12, 2021

Thanks for your pull request, @WalterBright!

Bugzilla references

Auto-close Bugzilla Severity Description
21821 normal Optimizer assumes immutables do not change, but they can in @System code

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

@Geod24
Copy link
Member

Geod24 commented Apr 12, 2021

As replied on the issue, changing immutable data is specified as UB currently, and IMHO should stay that way. Having @system bypass a scope checks is acceptable, but having it bypass type ctors would be a step back from the current state.

@WalterBright
Copy link
Member Author

buildkite fails with heisenbug:

Command Exit Status | -1 (Agent Lost)

@Geod24 half of my PRs don't make it through the test suite with random failures in the test suite. The fix, of course, is to recognize that the failure is a networking problem and automatically restart it. Can we get some of these addressed?

More and more tests keep getting added to the test suite, and soon it will become impossible to get anything through it without failing somewhere.

@Geod24
Copy link
Member

Geod24 commented Apr 12, 2021

@Geod24 half of my PRs don't make it through the test suite with random failures in the test suite. The fix, of course, is to recognize that the failure is a networking problem and automatically restart it. Can we get some of these addressed?

This should help: dlang/ci#444

@WalterBright
Copy link
Member Author

@Geod24 if you'll fix core.lifetime, I'll be happy to enable this again. Though I wonder what else may break that's casting away immutability.

@Geod24
Copy link
Member

Geod24 commented Apr 12, 2021

Casting away immutability is fine, it's mutating previously-immutable data that isn't. I'll take a look at core.lifetime.

@WalterBright
Copy link
Member Author

@Geod24 thanks! I'm currently busy tracking down another optimizer failure exposed by #12409

@PetarKirov
Copy link
Member

PetarKirov commented Apr 12, 2021

I'd say that most (all?) of the valid use cases of emplace involve in-place initializing some piece of fresh memory (e.g. std.experimental.allocator : make). So it's going from mutable void[] to immutable T. The part about accepting ref T target is an attempt at providing a minor convenience and safety vs void[]. Accepting ref immutable(T) is plain wrong, IMO.

@Geod24 I think the signature of copyEmplace should be changed to:

ref inout(S) copyEmplacex(
    ref inout(S) source,
    return ref S target)
{
    // ...
    return target; // cast to `inout(S)` if necessary.
}

@Geod24
Copy link
Member

Geod24 commented Apr 12, 2021

The code was introduced by dlang/druntime@0868bef so CC @kinke . The commit does mention that this is needed to allow calling differently-qualified copy ctor (e.g. immutable copy ctor). Is that really something users of emplace need ?

@kinke
Copy link
Contributor

kinke commented Apr 13, 2021

Is that really something users of emplace need ?

Apparently so: dlang/phobos#7655 / dlang/phobos#7661

@WalterBright
Copy link
Member Author

@kinke I see the code there that does the immutable, but it's missing the why code needs to run a postblit on an immutable object. Some design decision there looks terribly wrong.

@WalterBright
Copy link
Member Author

Ready to go

Copy link
Contributor

@dkorpel dkorpel left a comment

Choose a reason for hiding this comment

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

Meh... I don't mind a small performance regression in DMD's backend, but the real issue here is the UB from the code in druntime modifying immutable data.

@RazvanN7 RazvanN7 merged commit 951ab23 into dlang:master Feb 7, 2023
@WalterBright WalterBright deleted the fix21821 branch February 7, 2023 17:02
@ibuclaw
Copy link
Member

ibuclaw commented Feb 7, 2023

Meh... I don't mind a small performance regression in DMD's backend, but the real issue here is the UB from the code in druntime modifying immutable data.

Immutable is pretty much ignored anyway as it's initialized-once rather than read-only data.

I have no idea whether possible, but maybe the OS could assist, ie: mprotect() data after first write, so it'd cause a fault if written to again.

@anon17
Copy link

anon17 commented Feb 8, 2023

Yep, receiveOnly has wrong design, the ret tuple should be mutable storage and casted to Tuple!T on return.

@anon17
Copy link

anon17 commented Feb 8, 2023

A simple hack, closure:

    Tuple!(T) delegate() deret;

    thisInfo.ident.mbox.get((T val) {
        deret = (){ return val; };
    }...);
    static if (T.length == 1)
        return deret()[0];
    else
        return deret();

@ibuclaw
Copy link
Member

ibuclaw commented Feb 16, 2023

@WalterBright @RazvanN7 How do we know this fix works? The test is never ran by the testsuite!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backend glue code, optimizer, code generation Bug Fix Needs Approval Ready To Merge Let's get this merged
Projects
None yet
9 participants