Bug 10619 – Wrong local variable passed as alias arguments to templates

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-07-11T20:12:07Z
Last change time
2021-03-06T03:40:51Z
Keywords
pull, wrong-code
Assigned to
No Owner
Creator
hsteoh
Depends on
14831

Comments

Comment #0 by hsteoh — 2013-07-11T20:12:07Z
Code: -----snip----- import std.stdio; import std.algorithm; void main() { int[] arr = [3,4,2,1]; bool less(int a, int b) { return a < b; } bool greater(int a, int b) { return a > b; } { auto dg = &less; sort!(dg)(arr); } //this dg *should* be different from older destroyed dg //rename to dg2 and everything works as expected auto dg = &greater; sort!(dg)(arr); writeln(arr); //outputs [1,2,3,4] instead of [4,3,2,1] //change dg variable name in either place and it works //also, if you don't do the 1st sort, it works correctly even with same variable name } -----snip-----
Comment #1 by hsteoh — 2014-07-16T16:56:24Z
Looks like the problem is that the mangling of both instances of 'dg' is identical, so the compiler thinks that they are the same function.
Comment #2 by hsteoh — 2014-07-16T17:07:06Z
A slightly simpler test case: ----- import std.stdio; void myFunc(alias Sym)() { writefln("%s", Sym); } void main() { { { int x = 789; myFunc!x(); } int x = 456; myFunc!x(); } int x = 123; myFunc!x(); } ----- Expected output: ----- 789 456 123 ----- Actual output: ----- 789 789 789 -----
Comment #3 by hsteoh — 2014-07-16T17:32:07Z
A clearly legal case that's currently broken: ---- import std.stdio; void myFunc(alias Sym)() { writeln(Sym); } void main() { foreach (i; 0..3) { myFunc!i(); } foreach (i; 5..8) { myFunc!i(); } } ---- Expected output: ---- 0 1 2 5 6 7 ---- Actual output: ---- 0 1 2 2 2 2 ---- The two instances of 'i' are clearly in distinct scopes, yet they are conflated in the mangling of myFunc, leading to wrong generated code.
Comment #4 by sludwig — 2015-07-27T12:17:17Z
I assume that this has the same root cause: --- void checkAlias(X...)(int cmp) { assert(X[0] == cmp); } void main() { foreach (j; 0 .. 2) { if (j == 0) { int i = 42; checkAlias!(i)(i); // succeeds (42 == 42) } else { int i = 13; checkAlias!(i)(i); // fails (42 == 13) } } } --- This is a reduced test case of https://github.com/rejectedsoftware/vibe.d/issues/863
Comment #5 by k.hara.pg — 2015-07-27T13:13:42Z
(In reply to Sönke Ludwig from comment #4) > I assume that this has the same root cause: > > --- > void checkAlias(X...)(int cmp) { assert(X[0] == cmp); } > > void main() { > foreach (j; 0 .. 2) { > if (j == 0) { > int i = 42; > checkAlias!(i)(i); // succeeds (42 == 42) > } else { > int i = 13; > checkAlias!(i)(i); // fails (42 == 13) > } > } > } > --- > > This is a reduced test case of > https://github.com/rejectedsoftware/vibe.d/issues/863 Yes, it's same issue.
Comment #6 by k.hara.pg — 2015-07-27T13:14:52Z
*** This issue has been marked as a duplicate of issue 14831 ***
Comment #7 by moonlightsentinel — 2021-02-26T23:47:03Z
This issue remains when when (static) variables receive different manglings (see [1][2]). The problem is that the compiler treats those template instances as duplicates due to the bug in `Dsymbol.equals`. [1] https://github.com/dlang/dmd/pull/12119 [2] https://github.com/dlang/dmd/pull/12235
Comment #8 by dlang-bot — 2021-02-27T17:35:30Z
@MoonlightSentinel updated dlang/dmd pull request #12236 "Fix 10619 - Wrong local variable passed as alias arguments to templates" fixing this issue: - Fix 10619 - Wrong local variable passed as alias arguments to templates PR #12119 introduced `localNum` to differentiate between multiple symbols with identical names. But `Dsymbol.equals` doesn't consider this variable when comparing two Dsymbols. This caused template semantic to treat the second instantiation of `foo` as a duplice in the following example: ```d void main() { { int x = 1; foo!x(); } { int x = 2; foo!x(); } } ``` https://github.com/dlang/dmd/pull/12236
Comment #9 by dlang-bot — 2021-02-28T12:11:41Z
dlang/dmd pull request #12236 "Fix 10619 - Wrong local variable passed as alias arguments to templates" was merged into stable: - 9f980f52e6d798c06e6b7da55e12cf25882cc757 by MoonlightSentinel: Fix 10619 - Wrong local variable passed as alias arguments to templates PR #12119 introduced `localNum` to differentiate between multiple symbols with identical names. But `Dsymbol.equals` doesn't consider this variable when comparing two Dsymbols. This caused template semantic to treat the second instantiation of `foo` as a duplice in the following example: ```d void main() { { int x = 1; foo!x(); } { int x = 2; foo!x(); } } ``` https://github.com/dlang/dmd/pull/12236
Comment #10 by dlang-bot — 2021-03-06T03:40:51Z
dlang/dmd pull request #12253 "merge stable" was merged into master: - 0c2d8bd2abf22476acf98065252559145c481fef by MoonlightSentinel: Fix 10619 - Wrong local variable passed as alias arguments to templates PR #12119 introduced `localNum` to differentiate between multiple symbols with identical names. But `Dsymbol.equals` doesn't consider this variable when comparing two Dsymbols. This caused template semantic to treat the second instantiation of `foo` as a duplice in the following example: ```d void main() { { int x = 1; foo!x(); } { int x = 2; foo!x(); } } ``` https://github.com/dlang/dmd/pull/12253