Bug 9130 – Wrong codegen for compile time constructed struct

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
All
Creation time
2012-12-09T16:21:00Z
Last change time
2013-05-23T19:08:44Z
Keywords
wrong-code
Assigned to
nobody
Creator
samukha

Comments

Comment #0 by samukha — 2012-12-09T16:21:05Z
This is the minimal test case I have for now. Wrong value is generated for the 'name' member causing the following to segfault at runtime (1): struct S { void bar() { } } struct Meta { string name; void construct(alias m)() { name = "bar"; } } struct Function { Meta super_; alias super_ this; bool break_; void construct(alias f)() { super_.construct!f(); } void dynConstruct(alias f)() { if (!break_) { break_ = true; meta!(__traits(getOverloads, S, "bar")[0]); } } } @property void meta(alias m)() { static Function md = function() { Function r; r.construct!m(); return r; }(); assert(md.name == "bar"); // (1) md.dynConstruct!m(); } void main() { meta!(S.bar); }
Comment #1 by maxim — 2012-12-10T06:52:27Z
It happens because of invalid usage of traits. If spec is right, getOverloads works with classes and even if it does work with structs, dmd complains "need 'this' for bar type void()" struct S { void bar() { } } void meta(alias m) () { // insert some usage of m here // to force dmd to reject code } void main() { //Error: need 'this' for bar type void() //auto x = __traits(getOverloads, S, "bar")[0]; //But template silently 'eats' erroneous construct meta!(__traits(getOverloads, S, "bar")[0]); } In your code if you comment out "meta!(__traits(getOverloads, S, "bar")[0]);" everything would work fine.
Comment #2 by samukha — 2012-12-10T08:30:45Z
(In reply to comment #1) > It happens because of invalid usage of traits. If spec is right, getOverloads > works with classes and even if it does work with structs, dmd complains "need > 'this' for bar type void()" Sorry, it is a valid usage. There should be no restrictions on the kind of overloaded functions passed to getOverloads. > > struct S > { > void bar() { } > } > > void meta(alias m) () > { > // insert some usage of m here > // to force dmd to reject code > } > > void main() > { > //Error: need 'this' for bar type void() > //auto x = __traits(getOverloads, S, "bar")[0]; Sure, calling a member function without a context pointer will and should produce an error. Passing it to a template, storing in a tuple, getting its type, static address and other meta-data are valid operations and should be allowed. > //But template silently 'eats' erroneous construct > meta!(__traits(getOverloads, S, "bar")[0]); > } > > In your code if you comment out "meta!(__traits(getOverloads, S, "bar")[0]);" > everything would work fine. I need to use getOverloads. BTW, if you change S to a class and mark bar() static you will get the same segfault.
Comment #3 by maxim — 2013-02-04T00:55:34Z
Reduced: class S { void bar() { } } import core.stdc.stdio : printf; struct Function { int[] ai = [1,2,3]; } @property void meta(alias m)() { static Function md; printf("length = %d\n", md.ai.length); printf("ptr = %p\n", md.ai.ptr); md.ai[0] = 0; } void main() { meta!(__traits(getOverloads, S, "bar")[0]); meta!(S.bar); } Strangely dmd generates two functions and places two md objects in thread local storage (at least it reports do so). It seems that whatever __traits returns, is treated differently from S.bar. This leads to following problem. When above code is run, it outputs: length = 3 ptr = 0xc6c540 Segmentation fault So, thread local md object seems to be allocated, but array pointer is corrupted. If either of meta invocations is commented out, the code prints length = 3 ptr = 0x636298 So, pointer is valid. Ironically 0x636298 * 2 meta functions = 0xC6C530
Comment #4 by k.hara.pg — 2013-02-04T01:16:56Z
With git head and Windows 7 32bit PC, no segmentation fault occurs. I think you need to report actual environment and compiler version.
Comment #5 by maxim — 2013-02-04T01:20:55Z
(In reply to comment #4) > With git head and Windows 7 32bit PC, no segmentation fault occurs. > I think you need to report actual environment and compiler version. I used linux64 and git head (actually it was 2-3 days old).
Comment #6 by maxim — 2013-02-04T01:41:01Z
(In reply to comment #4) > With git head and Windows 7 32bit PC, no segmentation fault occurs. > I think you need to report actual environment and compiler version. Still happens with git head. Neither original, nor reduced example segfaults at runtime on windows on 2.061, so the issue seems to be either linux bug or common one but fixed in 2.061 windows release.
Comment #7 by clugdbug — 2013-05-07T23:43:50Z
Confirmed on Linux, it's actually a regression. This worked in 2.057, failed in 2.059.
Comment #8 by bugzilla — 2013-05-23T02:12:59Z
Comment #9 by github-bugzilla — 2013-05-23T18:07:37Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/8265f070e11cb59c7390957abd2f1257290bfd61 fix Issue 9130 - Wrong codegen for compile time constructed struct https://github.com/D-Programming-Language/dmd/commit/bb9a2a95d6f204cbb88a54a239069d4ddf0f23b5 Merge pull request #2068 from WalterBright/fix9130 fix Issue 9130 - Wrong codegen for compile time constructed struct