Bug 17258 – Pass by name doesn't work reliably and can sometimes lead to memory corruption
Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-03-15T17:22:31Z
Last change time
2019-05-25T08:57:01Z
Keywords
wrong-code
Assigned to
Suleyman Sahmi (سليمان السهمي)
Creator
ZombineDev
Comments
Comment #0 by petar.p.kirov — 2017-03-15T17:22:31Z
struct ByName1(alias Var)
{
alias var = Var;
}
struct ByName2(alias Var)
{
alias var = Var;
void inc() { var++; }
}
void byName2(alias var)()
{
var++;
}
void test1()
{
int x;
ByName1!x v;
v.var++;
assert(v.var == 1); // v.var is 1 => passes - OK
assert(x == v.var); // x is 0 => fails - NG
}
void test2()
{
int x;
ByName2!x v;
v.inc();
// import std.stdio;
// writeln(v.var); // Prints garbage !!!
assert(v.var == 1); // v.var is ??? => fails - NG
assert(x == v.var); // x is 0, v.var is ??? => fails - NG
}
void test3()
{
int x;
byName2!x();
assert (x == 1); // x is 1 => passes - OK
}
void main()
{
test1(); // fails because &x != &v.var
test2(); // fails because of bad code gen / memory corruption
test3(); // passes
}
Comment #1 by ag0aep6g — 2017-03-15T19:40:27Z
Looks like the compiler thinks `var` is a field. Writing to `v.var` then stomps over anything that's actually there.
----
struct ByName3(alias Var)
{
alias var = Var;
ubyte value = 1;
}
void main()
{
ushort x;
ByName3!x v;
ubyte w = 2;
v.var = 0xAA_BB; /* stomps over v.value and w */
import std.stdio;
writefln("%X", v.value); /* prints "BB", should be 1 */
writefln("%X", w); /* prints "AA", should be 2 */
}
----
Comment #2 by dlang-bot — 2019-05-25T08:57:01Z
dlang/dmd pull request #9884 "Fix issue 17258 - Alias parameter wrongly accessed as a field" was merged into stable:
- a21e8dfd606ae94b104b4a1a81b2c31476cf13ca by سليمان السهمي (Suleyman Sahmi):
Fix issue 17258 - Alias parameter wrongly accessed as a field
https://github.com/dlang/dmd/pull/9884