Skip to content

Fix Issue 23639 - Casting to shared not allowed with -preview=nosharedaccess#14836

Merged
RazvanN7 merged 1 commit intodlang:masterfrom
RazvanN7:Issue_23639
Jan 20, 2023
Merged

Fix Issue 23639 - Casting to shared not allowed with -preview=nosharedaccess#14836
RazvanN7 merged 1 commit intodlang:masterfrom
RazvanN7:Issue_23639

Conversation

@RazvanN7
Copy link
Contributor

@RazvanN7 RazvanN7 commented Jan 18, 2023

Casting to shared should be allowed even if the result is returned, read or written because the variable has just been "promoted" to shared so it's not being actually shared with anyone. This is currently blocking the templatization of the __d_new_class runtime hook (cc @teodutu ).

@RazvanN7 RazvanN7 added the Review:Blocking Other Work review and pulling should be a priority label Jan 18, 2023
@dlang-bot
Copy link
Contributor

dlang-bot commented Jan 18, 2023

Thanks for your pull request and interest in making D better, @RazvanN7! 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
23639 blocker Casting to shared not allowed with -preview=nosharedaccess

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

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.

Given it's still in preview, and in the absence of anything better, I think this is okay.
However, I think this will permit this:

shared string s;
string s2 = cast(shared) s;

So it might need more thought long term.

@RazvanN7
Copy link
Contributor Author

No it doesn't. If you run that code it gives: "direct access to shared s is not allowed, see core.atomic"

@dkorpel
Copy link
Contributor

dkorpel commented Jan 18, 2023

Oh, that's good

@maxhaton
Copy link
Member

Isn't this a special case patching over an issue with the nosharedaccess check?

IIRC this same issue also breaks nosharedaccess atomics with ldc because the cast is badly analyzed and/or then "optimized" to strip out the shared (this is actually tested with a static assert somewhere in the test suite)

Copy link
Contributor

@thewilsonator thewilsonator left a comment

Choose a reason for hiding this comment

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

Couple of thing I'd like clarified before this is merged.

if (e.type.isShared())
// https://issues.dlang.org/show_bug.cgi?id=23639
// Should be able to cast(shared)
if (!e.isCastExp() && e.type.isShared())
Copy link
Contributor

Choose a reason for hiding this comment

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

what does this do to const shared?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you cast to const shared it just performs the cast.

Copy link
Contributor

Choose a reason for hiding this comment

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

please augment the test case then.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why? Before this patch the cast would not have been allowed, but now it is allowed. Note that the code would fail because you cannot convert a const(shared) to a shared.

{
void *p;
// assume p is allocated here
return cast(shared(T))p;
Copy link
Contributor

Choose a reason for hiding this comment

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

what is the @safety of this operation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Error: cast from void* to shared(T) not allowed in safe code

The expected @safety level - @System.

Copy link
Contributor

Choose a reason for hiding this comment

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

and if typeof(p) == T?

Copy link
Contributor Author

@RazvanN7 RazvanN7 Jan 19, 2023

Choose a reason for hiding this comment

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

The modified code has nothing to do with the safety checks. Casts to differently qualified types remain unsafe, that part is not modified.

Copy link
Contributor

Choose a reason for hiding this comment

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

-preview=nosharedaccess is all about safety. even if the end result is that the code must be system. Perhaps I was thinking things wrong, but it seems to me that the only reason why you would want to do this with -preview=nosharedaccess is because you have a unique reference to an object you then want to share. Its fine if that needs to be trusted, then please disregard this request for changes, but please do document this discussion in the test case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, a prime example of this is memory allocation. You allocate heap memory which is naturally shared among threads and you want to express that. What other way of casting the mallocd memory to shared is there?

@RazvanN7
Copy link
Contributor Author

RazvanN7 commented Jan 19, 2023

Isn't this a special case patching over an issue with the nosharedaccess check?

Well, -preview=nosharedaccess does not allow free access to shared variables. The implementation simply checks if the type of an expression is shared and then errors out (provided, core.atomic is not used). This includes cast expressions to shared types. Note that casting a shared type to an unshared type works without this patch, so it is reasonable that doing the opposite works.

You call this patch special casing. Fine, but I have no idea what is the general problem other than "casting to shared is not allowed".

IIRC this same issue also breaks nosharedaccess atomics with ldc because the cast is badly analyzed and/or then "optimized" to strip out the shared (this is actually tested with a static assert somewhere in the test suite)

Without a test case, I have no idea what you are referring to.

@RazvanN7
Copy link
Contributor Author

RazvanN7 commented Jan 20, 2023

@thewilsonator I have added a fail_compilation test.

@maxhaton Ping. This is blocking progress on templating druntime hooks.

@RazvanN7 RazvanN7 merged commit 67c137a into dlang:master Jan 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review:Blocking Other Work review and pulling should be a priority Severity:Bug Fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants