fix Issue 18868 - nondeterministic static ctor/dtor#8255
fix Issue 18868 - nondeterministic static ctor/dtor#8255dlang-bot merged 1 commit intodlang:masterfrom
Conversation
|
Thanks for your pull request and interest in making D better, @JohanEngelen! 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 references
|
|
If the same static this is instantiated several times due to different template extraction, using the line number would create false-positive on the duplicate detection. |
| * Generate deterministic named Id based on the `loc` such that | ||
| * the naming is consistent across multiple compilations. | ||
| * `prefix` must be a null-terminated string. | ||
| */ |
There was a problem hiding this comment.
New functions should have standard Ddoc sections like Returns: and Params.
| @@ -0,0 +1,28 @@ | |||
| module imports.test18868_fls; | |||
|
|
|||
| template FLS(T) { | |||
There was a problem hiding this comment.
Curly braces on their own lines.
|
|
I don't see how the jenkins failure is related to this PR. |
|
I restarted Jenkins, let's hope it was just a spurious failure in Ocean. |
|
@wilzbach Thanks, but it still fails :( |
|
Confirmed not related to this PR: #8257 has the same problem. |
src/dmd/identifier.d
Outdated
| * Identifier (inside Identifier.idPool) with deterministic name based | ||
| * on the source location. | ||
| */ | ||
| static Identifier generateIdWithLoc(const(char)* prefix, const ref Loc loc) |
There was a problem hiding this comment.
Any reason this can't be string prefix ?
There was a problem hiding this comment.
No, this should be string. Except when I do that:
dmd/identifier.d(151): Error: string is used as a type
Turns out Identifier has a const char* member called string! >_<
There was a problem hiding this comment.
@WalterBright I've changed it to string, by prefixing with .. Ugly, but this PR shouldn't become a refactoring of Identifier. I'll do that now in another PR.
There was a problem hiding this comment.
The refactoring PR has been merged now, the leading dot can now be removed?
|
Regarding the Jenkins failure - yes, the Ocean failure unrelated. |
src/dmd/identifier.d
Outdated
| * such that the name is consistent across multiple compilations. | ||
| * Params: | ||
| * prefix = first part of the identifier name. | ||
| * loc = source location to use is the identifier name. |
There was a problem hiding this comment.
is doesn't sound correct. Should it be in?
There was a problem hiding this comment.
Actually, I think think it should be "as".
|
Please squash commits when done. |
|
all done |
|
Should this go to the stable branch? |
It's a fairly critical bug, I find. |
|
Rebased and retargeted to |
|
I don't understand why it is failing after rebasing onto stable. It's failing on a "__unittest*" declaration, but that name has not changed with this PR (the code is almost identical, replacing a printf with a number of print statements...). Don't know what's happening here... |
|
The source location is not unique enough, we need another unique-ifying deterministic term: static foreach(s; ["666", "777"]) {
mixin(genCtor(s));
}
int i;
string genCtor(string a)
{
return "static this() { i += " ~ a ~ "; }";
}
void main()
{
assert(i == 0 + 666 + 777);
} |
|
Maybe add a counter to compilation unit that can be incremented each time an id is generated and appended to the location-based identifier. |
That won't be deterministic because it will depend on the order in which things are compiled. |
|
The only thing that comes to mind is a "static foreach iteration counter". They will have to be recursivable (i.e.: if there is a static foreach inside another static foreach). |
|
Last time I thought about this (it's been a year or so since), my conclusion was that the way to go for these issues was to stick with a counter, but to make it local within each scope. Scope in this sense means everything that is possibly an "entry point" for semantic analysis, i.e. modules, template instances, etc. The scope name would be part of the mangled symbol name, and within each such scope care would have to be taken that semantic analysis always proceeds linearly to make sure the symbol indices are stable. There might be a few tricky cases to take care of regarding on-demand semantic analysis of forward references (i.e. we might need to disallow some more cyclic dependencies), but something like this is the only universal scheme I managed to come up with. |
|
What about using both? Both file name plus line number and a counter. Try to have a local counter so it will be 0 in most cases. |
By the time you have a scheme that is stable for separate compilation, file name and line number don't serve to disambiguate any further. You can still include them to aid humans in tracing back symbol names to source code, of course. |
I think this won't work unless you define a new scope for each different particular template instantiation of the same source template. Because the order in which those are SemA'd is not deterministic. An easy approach for this is (using nameclash as poor man's "scope detection" ;-)) : use linenumber+columnnumber. If a new symbol is generated and that name already exists: suffix with ever increasing counter. I'll implement this scheme and see if that does work well:
Extra problematic issue is that the current mixin linenumber scheme is already flawed:
|
|
This PR also fixes https://issues.dlang.org/show_bug.cgi?id=18880 which is the same issue that is plaguing the static ctor/dtors. |
|
I've implemented a basic version of the proposed unique-ify scheme. |
jacob-carlborg
left a comment
There was a problem hiding this comment.
The code changes look good to me, not sure if it will be enough to fix the problems.
src/dmd/identifier.d
Outdated
| buf.print(loc.charnum); | ||
| auto basesize = buf.peekSlice().length; | ||
| uint counter = 1; | ||
| while (stringtable.lookup(buf.peekSlice().ptr, buf.peekSlice().length) !is null) { |
There was a problem hiding this comment.
Curly braces on their own lines.
|
All good now, ready for merging. |
Instead of using a counter to create unique static ctor and dtor function identifiers, use the deterministic line+column location that is also used for unittests. The further disambiguate mixin instantiations on the exact same location, use a local counter.
|
Squashed and rebased into one commit onto current master. |
|
The semaphoreci failure is unrelated (the semaphore testing is very flaky, do more people experience that?). |
|
Would appreciate if someone could restart the semaphoreci tester. |
|
Restarted SemaphoreCi (and added you to the SemaphoreCI collaborators) Seems like https://github.com/dlang/dmd/blob/master/test/runnable/externmangle.d was recently modified... |
Instead of using a counter to create unique static ctor and dtor function identifiers, use the deterministic line+column location that is also used for generating unittest function identifiers.