Bug 14038 – [REG2.067a] Non-mutable AA initialization segfaults in runtime

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-01-24T22:42:00Z
Last change time
2015-01-25T00:34:25Z
Keywords
pull, wrong-code
Assigned to
nobody
Creator
k.hara.pg

Comments

Comment #0 by k.hara.pg — 2015-01-24T22:42:48Z
From: http://forum.dlang.org/thread/[email protected] With git-head, this code segfaults in runtime. static immutable words = [ `zero`, `one`, `two` ]; static immutable ubyte[string] wordsAA; static this() { foreach (ubyte i, e; words) { wordsAA[e] = i; } } The regression had introduced by the combination of: https://github.com/D-Programming-Language/dmd/pull/4159 https://github.com/D-Programming-Language/druntime/pull/1037 The core issue is in dmd e2ir.c around lien 4570. void visit(IndexExp *ie) { ... Type *t1 = ie->e1->type->toBasetype(); if (t1->ty == Taarray) { // set to: // *aaGetY(aa, aati, valuesize, &key); // or // *aaGetRvalueX(aa, keyti, valuesize, &key); TypeAArray *taa = (TypeAArray *)t1; ... elem* ti; if (ie->modifiable) { n1 = el_una(OPaddr, TYnptr, n1); s = aaGetSymbol(taa, "GetY", 1); ti = toElem(getInternalTypeInfo(taa, NULL), irs); // <--- } else { s = aaGetSymbol(taa, "GetRvalueX", 1); ti = toElem(getInternalTypeInfo(taa->index, NULL), irs); } //printf("taa->index = %s\n", taa->index->toChars()); //printf("ti:\n"); elem_print(ti); elem* ep = el_params(n2, valuesize, ti, n1, NULL); If ie->modifiable (the IndexExp appears in left hand side of an assignment expression), typeid(taa) is set to the 2nd argument of _aaGetY(). But, if taa is not mutable, it will be a TypeInfo_Const reference that points TypeInfo_AssociativeArray. On the other hand, the _aaGetY() function is defined as: void* _aaGetY(AA* aa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey) { if (aa.impl is null) { aa.impl = new Impl(); aa.impl.buckets = aa.impl.binit[]; aa.impl.firstUsedBucket = aa.impl.buckets.length; aa.impl._keyti = cast() ti.key; // <----- } return _aaGetImpl(aa, ti.key, valuesize, pkey); } And ti does not point an instance of TypeInfo_AssociativeArray, so will cause segfault at the ti.key access.
Comment #1 by k.hara.pg — 2015-01-24T22:45:52Z
More better test case: class C { immutable ubyte[string] wordsAA; this() { wordsAA["zero"] = 0; // segfaults } } void main() { auto c = new C(); } The original code is initializing immutable AA inside foreach loop. I think it would be a multiple variable initialization and essentially should be disallowed.
Comment #2 by k.hara.pg — 2015-01-24T22:50:01Z
(In reply to Kenji Hara from comment #1) More close to the original: static immutable ubyte[string] wordsAA; static this() { wordsAA["zero"] = 0; } void main() {}
Comment #3 by k.hara.pg — 2015-01-24T22:54:21Z
Comment #4 by github-bugzilla — 2015-01-25T00:34:24Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/0044e35b0e4d24435bebb15461dd170ccd59fe78 fix Issue 14038 - Non-mutable AA initialization segfaults in runtime https://github.com/D-Programming-Language/dmd/commit/47ff8276ab022b7846dc493e838e5a0703a71937 Merge pull request #4334 from 9rnsr/fix14038 [REG2.067a] Issue 14038 - Non-mutable AA initialization segfaults in runtime