Fix 15371: Disable access checks for __traits(getMember) and relatives.#9325
Fix 15371: Disable access checks for __traits(getMember) and relatives.#9325LightBender wants to merge 5 commits intodlang:masterfrom
Conversation
|
Thanks for your pull request and interest in making D better, @LightBender! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
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 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#9325" |
|
Please use a better commit message and PR title. Something else than jus the link, like the title of the issue. |
ghost
left a comment
There was a problem hiding this comment.
Sorry but this bug fix is formally not ok. Also This is is a serious change that requires a DIP, which is all about the new super omnisciencynessment that the change bring.
|
Umm, what? How does fixing a genuine bug, which is acknowledge as something that should be fixed in the comment sitting above the code require an entire DIP? Your assertion is going to require a very detailed explanation to convince me of it's correctness. |
|
My thoughts on trying to fix this issue: This is a major step forward in term of metaprogramming. You know everything by using |
|
TBH, this is how i think this issue should be fixed. |
|
How is it a "major change to language semantics"? Futhermore, you did not explain WHY you consider this a major change to the language semantics, only repeated your assertion that it is. At this time I cannot accept your argument. |
ghost
left a comment
There was a problem hiding this comment.
Sorry for the confusing review comments yesterday @LightBender, if the issue can be solved as simply as that then it's nice.
jacob-carlborg
left a comment
There was a problem hiding this comment.
-
The change affects more than just
getMember, the tests should include a test for each trait it affects -
Even though this is fixing a bug, I think a changelog entry should be included. This adds new functionality and therefore should have a changelog entry explaining the new behavior. Have a look in the
changelogdirectory
| } | ||
| auto field = __traits(getMember, test, "privateField"); | ||
| printf("Existing private field value: %d\r\n", field); | ||
| field = 1; |
There was a problem hiding this comment.
Doesn't this just update a local variable?
| TEST_OUTPUT: | ||
| --- | ||
|
|
||
| --- |
There was a problem hiding this comment.
Shouldn't there be any output?
There was a problem hiding this comment.
That was the weird part, I could get the output when I placed an failing assert in the code, but without it, I got nothing.
There was a problem hiding this comment.
I think TEST_OUTPUT is usually used for asserting error messages for failing tests. Is there any difference if you print to stderr?
There was a problem hiding this comment.
You need to use pragma(msg,...) for TEST_OUTPUT as it only listens to output during compilation.
| auto test = new Test15371(); | ||
| const auto hasMember = __traits(hasMember, test, "privateField"); | ||
| if (hasMember) { | ||
| printf("_traits(hasMember) found privateField\r\n"); |
There was a problem hiding this comment.
I've never seen anyone use \r\n when printing to the console.
There was a problem hiding this comment.
Without it is just kept printing on the same line. And only with the failing assert.
There was a problem hiding this comment.
I mean, only \n is usually used.
There was a problem hiding this comment.
This works correctly on Windows too.
There was a problem hiding this comment.
You almost never need \r on Windows, too.
There was a problem hiding this comment.
It's an ingrained habit from the bad old days. I'll remove it.
|
|
||
| void main() { | ||
| auto test = new Test15371(); | ||
| const auto hasMember = __traits(hasMember, test, "privateField"); |
There was a problem hiding this comment.
auto is not required.
There was a problem hiding this comment.
Habit from my C# days where any variable decl would be var if it had the type somewhere in the initializer.
| auto virtualMethods = __traits(getVirtualMethods, test, "overload").length; | ||
| printf("Found %d virtual methods for private method 'overload'\r\n", virtualMethods); | ||
| auto virtualFunctions = __traits(getVirtualFunctions, test, "overload").length; | ||
| printf("Found %d virtual functions for private method 'overload'\r\n", virtualFunctions); |
There was a problem hiding this comment.
This looks quite dense, perhaps add some blank lines.
|
|
||
| The following traits can now access non-public members: | ||
| $(UL | ||
| $(LI hasMember) |
There was a problem hiding this comment.
I think this worked before this PR. Since this is not try to access the symbol. I'm guessing that what's ignoresymbolvisibility is for.
| $(LI getVirtualFunctions) | ||
| ) | ||
|
|
||
| This fixes a long-standing issue in D where the allMembers trait would correctly return non-public members but those non-public members would be inaccessible to other traits. |
There was a problem hiding this comment.
I suggest adding backticks (to indicate code) around allMembers.
| @@ -0,0 +1,31 @@ | |||
| // EXTRA_SOURCES: imports/test15371.d | |||
|
|
|||
There was a problem hiding this comment.
Runnable tests are very expensive. Please move this to compilable and use things like static assert or pragma(msg).
|
@LightBender Will you take this to the finish line or should I adopt it? |
|
@RazvanN7 I recommend you take it so it’s completed as soon as possible. |
|
PR submitted: #9585 . Closing this as @LightBender seems to have abandoned it. We can continue the discussion on the new PR. |
Removes access checks for
__traits(getMember)and relatives. This should have been done a long time ago. As it stands right now .offsetof is useless because it cannot be used on non-public members and therefore cannot be used to accurately map the type. Indeed there is NO way to accurately map any type that contains private data.Bug: https://issues.dlang.org/show_bug.cgi?id=15371