Bug 20025 – alias this combined with a copy constructor seems to lead to undefined behaviour.

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2019-07-04T07:08:35Z
Last change time
2019-07-04T12:20:14Z
Keywords
pull
Assigned to
No Owner
Creator
big.friendian

Comments

Comment #0 by big.friendian — 2019-07-04T07:08:35Z
Running the following code prints a random integer every time. If the copy constructor is removed, the code functions as expected (prints '77'). import std.stdio; struct B { static int value = 77; alias value this; this(ref return scope inout B rhs) inout { } } void test(int x) { writefln("x: %s", x); } int main() { B b; test(b); return 0; }
Comment #1 by simen.kjaras — 2019-07-04T08:16:10Z
A slightly more elucidating example: struct B { static int value = 77; alias value this; int i = 13; this(ref B rhs) { } } void test(ref int x, ref B b) { import std.stdio : writeln; writeln("x: ", &x, " = ", x); writeln("b: ", &b); } unittest { B b; test(b, b); } x is now consistently 13, and &x == &b. IOW, alias this is somehow forgetting that value is a static field, and treats it as non-static.
Comment #2 by big.friendian — 2019-07-04T08:56:38Z
The 'static' might be a bit of a red herring, in the code I wrote, I get the same behaviour whether 'value' is static or not.
Comment #3 by dlang-bot — 2019-07-04T09:12:30Z
@RazvanN7 created dlang/dmd pull request #10137 "Fix Issue 20025 - alias this combined with a copy constructor seems to lead to undefined behaviour." fixing this issue: - Fix Issue 20025 - alias this combined with a copy constructor seems to lead to undefined behaviour. https://github.com/dlang/dmd/pull/10137
Comment #4 by simen.kjaras — 2019-07-04T09:28:07Z
There seems to be a lot inconsistencies here. This code: struct S(bool _static, bool _field) { static if (_static) static int value = 77; else int value = 77; static if (_field) int field = 13; alias value this; this(ref S rhs) { } string toString() { return (_static ? "static, " : "non-static, ") ~ (_field ? "field" : "empty"); } } void test(T)(int i, ref int j, T t) { import std.stdio; writeln(t, ":"); writeln(" by val: ", i); writeln(" by ref: ", j); } void test(T)(T t) { test(t, t, t); } unittest { test(S!(true, true)()); test(S!(true, false)()); test(S!(false, true)()); test(S!(false, false)()); } Prints this on my machine (2.087.0): static, field: by val: 77 by ref: 13 static, empty: by val: 7771469 by ref: 0 non-static, field: by val: 77 by ref: 77 non-static, empty: by val: 77 by ref: 77 And this on run.dlang.io (also 2.087.0): static, field: by val: 2007830860 by ref: 13 static, empty: by val: 2007830868 by ref: 0 non-static, field: by val: 2007830848 by ref: 77 non-static, empty: by val: 2007830860 by ref: 77 The correct behavior, of course, is what's seen on my machine for both the non-static cases.
Comment #5 by dlang-bot — 2019-07-04T12:20:14Z
dlang/dmd pull request #10137 "Fix Issue 20025 - alias this combined with a copy constructor seems to lead to undefined behaviour." was merged into stable: - dde9964028a7cddcda7effb54dba384f358a1bb6 by RazvanN7: Fix Issue 20025 - alias this combined with a copy constructor seems to lead to undefined behaviour. https://github.com/dlang/dmd/pull/10137