Bug 5131 – Segfault(expression.c) opAssign and associative arrays (AA) are broken for types != this
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2010-10-29T11:42:00Z
Last change time
2010-11-07T17:46:04Z
Keywords
ice-on-valid-code, patch
Assigned to
nobody
Creator
sandford
Comments
Comment #0 by sandford — 2010-10-29T11:42:39Z
Using DMD 2.050, when trying to assign a value to an associative array that is not the type of the AA results in an ICE.
Here are two test cases:
import std.variant;
void main() {
Variant[string] a;
a["ICE?"] = 1;
}
------------------------
struct ICE {
ICE opAssign(int x) { return this; }
};
void main() {
ICE[string] a;
a["ICE?"] = 1;
}
Note that:
void main() {
Variant[string] a;
a["ICE?"] = Variant(1);
}
compiles correctly. See http://d.puremagic.com/issues/show_bug.cgi?id=2451
Comment #1 by clugdbug — 2010-10-31T00:58:35Z
With val[key] = e2, the temporary variable needs to be of typeof(val), not typeof(e2).
PATCH:
expression.c, AssignExp::semantic(), line 8974.
Expression *e = op_overload(sc);
if (e && e1->op == TOKindex &&
((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray)
{
// Deal with AAs (Bugzilla 2451)
// Rewrite as:
- // e1 = (typeof(e2) tmp = void, tmp = e2, tmp);
+ // e1 = (typeof(aa.value) tmp = void, tmp = e2, tmp);
+ Type * aaValueType = ((TypeAArray *)((IndexExp *)e1)->e1->type->toBasetype())->next;
Identifier *id = Lexer::uniqueId("__aatmp");
- VarDeclaration *v = new VarDeclaration(loc, e2->type,
id, new VoidInitializer(NULL));
+ VarDeclaration *v = new VarDeclaration(loc, aaValueType,
id, new VoidInitializer(NULL));
v->storage_class |= STCctfe;
Expression *de = new DeclarationExp(loc, v);
VarExp *ve = new VarExp(loc, v);