-
-
Notifications
You must be signed in to change notification settings - Fork 608
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 18554 - tupleof ignoring private shouldn't be accepted in @… #8035
Conversation
|
Thanks for your pull request, @WalterBright! Bugzilla references
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Yet another hole fixed :)
| @@ -112,11 +110,16 @@ enum SCOPE | |||
| compile = 0x0100, /// inside __traits(compile) | |||
| ignoresymbolvisibility = 0x0200, /// ignore symbol visibility | |||
| /// https://issues.dlang.org/show_bug.cgi?id=15907 | |||
| onlysafeaccess = 0x0400, /// unsafe access is not allowed for @safe code | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Shouldn't this be named onlyunsafeaccess, onlysystemaccess or nosafeaccess as it prevents @safe access but allows unsafe access?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's going to bite me later, I fear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Is this a good idea? It broadens the meaning of @safe beyond memory safety. This might open a can of worms for other code considered unsafe. |
|
@WalterBright Please consider leaving PRs open for at least 24 hours to allow time for everyone to have their say. |
|
one example use case of |
| @@ -3139,7 +3139,7 @@ private extern(C++) final class DotExpVisitor : Visitor | |||
|
|
|||
| e = new TupleExp(e.loc, e0, exps); | |||
| Scope* sc2 = sc.push(); | |||
| sc2.flags = sc.flags | SCOPE.noaccesscheck; | |||
| sc2.flags |= global.params.vsafe ? SCOPE.onlysafeaccess : SCOPE.noaccesscheck; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this should be tied to DIP 1000 (global.params.vsafe). DIP 1000 is about scope. But this has nothing to do with scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other precendents breaking changes were introduced with -dip1000 as it's effectively unused, e.g. #8036 (there were more in the last weeks, but I can't find them on the first try).
I guess eventually dip1000 might evolve in a sublanguage :/
|
Yet another regression without thinking of the consequences 😞. Come on people, can we please do better than this! |
It's not a regression (per se), because it's only active in the transitional Regarding the motivation - check Bugzilla: Copy/Paste
The And the issue reduced to its core (https://run.dlang.io/is/reMMQt): |
To be honest, I missed it was only for DIP1000.
How is this going to be handled when dip1000 is the default? Doesn’t sound likely that every change that dip1000 introduced can be turned into a deprecation. How are the examples related to memory safety? BTW, I don’t think that anyone would accidentally use tupleof. That other things dip1000 protests against is more likely to happen by accident. |
The idea is @safe offers a guarantee, not a "guarantee unless you use tupleof". The latter introduces a hole that will be very hard for reviewers to find, and impossible to guard against. |
A struct may present an @safe interface to users, but internally have private unsafe pointers. tupleof allows any code to have access to those private members, and can mess up the invariants relied on by the struct. Even int fields are not safe to access, as they may be used as an index to a pointer. If you're going to access private members in another module, bypassing the safe interface provided by that module, you're in @System land. |
Presumably by adding the equivalent of a |
|
Accessing private data is not memory unsafe by itself, though it might corrupt data in other ways. @safe has never been about encapsulation so far, though. Please note that this no longer compiles with -dip1000: Error: |
|
That error is about phobos still not working with -dip1000. It's the same for 2.079: https://run.dlang.io/is/mAwL0j |
|
Ah, ok. I just tried it against 2.078 which still accepts it. BTW: "latest" in the list of all compilers on run.dlang.io seems to be 2.078, while "nightly" seems to be about a month old. |
That is an encapsulation issue that |
Hmm, it gets updated daily by a cron which still seems to work: https://run.dlang.io/is/zx3psE How did you infer that it's outdated? |
Yes it is. Please refer to my previous explanation as to why. Encapsulating unsafe code and providing a safe interface is essential, and @safe code must respect the encapsulation. |
If I add --version as a command line option to dmd-nightly, I get |
That might be true but there is nothing about encapsulation in the documentation of |
That's why I said "access private members in another module". Code in the same module has always been allowed to access private members, this is quite deliberate. The idea is that it eliminates the need for the awful C++ "friend" hack, and presumably the programmer of the module knows what he's doing. Importing a module is another thing entirely.
Encapsulation of system code is fundamental to D's safety system. |
I don't doubt that. But just to repeat mself: the language specification does not mention that So far the story has been: "If you want to scrutinize the safety of your code marked |
Maybe this warrants a new visibility attribute that's more restrictive than Or let |
|
@WalterBright sounds like in this case the module is the unit of (this would be true at aggregate scope even if accessing private was limited to the same aggregate, so that's not the problem) |
|
This leads to a wider question about what "valid state" is when passed to an |
…safe code