add -preview=nosharedaccess flag and implementation#10209
add -preview=nosharedaccess flag and implementation#10209dlang-bot merged 1 commit intodlang:masterfrom
Conversation
|
Thanks for your pull request, @WalterBright! Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + dmd#10209" |
|
This is important because @TurkeyMan needs it to clinch a design win for D. It's structured to no interfere with the rest of the compiler. He's also set up to use it immediately and see if it is suitable or not. |
| i = *p; | ||
| i = a[0]; | ||
| i = s.si; | ||
| i = t.i; |
There was a problem hiding this comment.
Should the test prove that writes are denied too?
I feel like it might also be good to prove that taking the address is okay, and passing by pointer/ref.
There was a problem hiding this comment.
Sorry, I missed that one hiding in there.
There was a problem hiding this comment.
I suppose those other tests are implied by the function arguments.
There was a problem hiding this comment.
please assert that passing a shared argument to non shared parameter fails like it is supposed to.
|
Thank you so much! |
26ec1b3 to
2a23a4e
Compare
|
@TurkeyMan I expect you'll give it a good thrashing, and expect to have to tweak it here and there. |
2a23a4e to
b01e63d
Compare
|
I most certainly will. I have been implementing our machinery in D, which is tricky, because I have to maintain compatibility with the C++, but it's not really a port rather than a re-image of the API with shared stuff woven through. |
|
speaking of incomplete, this needs to be disallowed: otherwise e.g. |
|
This is nicely implemented but honestly this looks like a warning with |
|
@thewilsonator the |
The idea is to make it a non-optional language feature. |
|
touché. Ignore that then. |
|
I'll update my proposed DIP on this to match. |
|
The following should fail, and yet it does not Do you see now why I implemented it the way I did? |
|
| rs.exp = inferType(rs.exp, fld.treq.nextOf().nextOf()); | ||
|
|
||
| rs.exp = rs.exp.expressionSemantic(sc); | ||
| rs.exp.checkSharedAccess(sc); |
|
@Geod24 I am not sure if we want to get into the habit of special casing storage classes on basic types? |
|
It's true that copying an |
|
So we're talking about this right? void fun()
{
shared int x = 10;
int y = x;
}It's not clear to me what the I suppose this is valid: void fun()
{
shared int x = 10;
shareWithOtherThreads(&x);
int y = x;
}Now x is not necessarily thread-local... although it IS on the local stack, so any foreign thread is gonna be hitting dangling stack memory in a few nanoseconds. Safe to expect that function must join internally. This may be the trouble case: void fun()
{
shared int x = 10;
shareWithOtherThreads(&x);
int y = x;
joinOtherThreadsThatMayStillHaveX();
}This is highly contrived, but it's a theoretical problem case with shared local values assigning back to non-shared. |
b01e63d to
5cc1462
Compare
It fails now. |
|
I'm not sure failing is right, but it's the conservative option, and we should do that for now until we can prove any situation where that assignment should be expected to work, and understand the context. |
5cc1462 to
2b43470
Compare
|
This should fail: because it is reading |
That's true, but the failure should be reported at the point the variable is read. shared int val;
int read(int x) { return x; }
void main () {
read(val); // This fails
shared int* gelVal = ...;
read(*getVal); // Fails
}But the originally provided snipped should not fail, because it does not read a |
|
I simply don't understand your comment, in that it isn't clear what you tested this PR doing and what you expected it to and what was the piece of code you tested. |
|
Test: void foo() { shared int i; }Expected result: Compiles
|
|
@Geod24 That's because the code generated is: Note the initialization. That's a write to Manu will be using this initially, so I'm going to rely on his experience for some guidance here. |
|
Not that is should be cause to delay testing but that error message should definitely be improved since is not at all immediately obvious that is contains an initialisation that is a write. |
|
Polishing error messages is good but is something we should do after the design has been shown to be successful. Essentially, @TurkeyMan needs this PR now, and it doesn't hurt anything to get it incorporated, since the behavior is enabled with a switch. |
| { | ||
| if (!global.params.noSharedAccess || | ||
| sc.intypeof || | ||
| sc.flags & SCOPE.ctfe) |
There was a problem hiding this comment.
This line and the previous one should be doubly indented lest there is confusion with the body of the if statement.
There was a problem hiding this comment.
added { ... } for that.
2b43470 to
c05b9ad
Compare
Default initialization can never execute arbitrary code. |
|
I am concerned about the initialisation logic in this patch too, but I doubt I'll have issues with it personally, since in all my use cases, data is not constructed shared, it's promoted.
I expect 2 should work right now, and 1 should be made to work. 3 and maybe options to make 2 smoother could be considered in the future. |
|
This fails to compile private extern(C) void _d_setSameMutex(shared Object ownee, shared Object owner) nothrow;
void setSameMutex(shared Object ownee, shared Object owner)
{
_d_setSameMutex(ownee, owner);
}It seems classes are unhandled. |
This is a simple implementation of the idea that shared data should not be directly accessed, but should only be accessed via
core.atomicprimitives.It's intended to replace #10142 which I don't think is the right approach, and is incomplete.