Bug 874 – Bad codegen: wrong value variable in tuple foreach, D1 only

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
All
Creation time
2007-01-22T22:12:00Z
Last change time
2014-02-15T13:12:53Z
Keywords
patch, wrong-code
Assigned to
nobody
Creator
jarrett.billingsley

Comments

Comment #0 by jarrett.billingsley — 2007-01-22T22:12:26Z
I don't know how else to describe this. template AA(V, K) { V[K] AA(T...)(T args) { V[K] ret; K key; foreach(i, arg; args) { static if(!(i & 1)) key = arg; else ret[key] = arg; } return ret; } } void main() { char[][char[]] array = AA!(char[], char[])("a", "b", "c", "d"); writefln("length = ", array.length); foreach(k, v; array) writefln("array[", k, "] = ", v); } This code will give bizarre output when printing out the contents of the returned AA. This usually is weird characters, and usually results in a "4invalid UTF-8 sequence" exception. Stranger still, the output changes depending on how many string literals there are in main(). This happens in both -debug and -release modes, although they give different output.
Comment #1 by thomas-dloop — 2007-02-23T16:36:10Z
Comment #2 by clugdbug — 2009-08-12T06:17:48Z
The equivalent code (below) works correctly on D2. This is a D1-only bug. --------- import std.stdio; template AA(V, K) { V[K] AA(T...)(T args) { V[K] ret; K key; foreach(i, arg; args) { static if(!(i & 1)) key = arg; else ret[key] = arg; } return ret; } } void main() { string[string] array = AA!(string, string)("a", "b"[], "c"[], "d"[]); writefln("length = %d\n", array.length); foreach(k, v; array) writefln("array[%d]=%s", k, v); }
Comment #3 by clugdbug — 2009-10-30T01:53:50Z
Original title was: "Incorrect codegen with tuples, string constants, and AAs". This bug has nothing to do with AAs, actually. The problem is that the 'value' in a tuple foreach isn't dealt with correctly. Workarounds: Change the code into: ret = arg.dup; or ret = args[0]; char[] bug874(T...)(T args) { char[] ret; foreach(arg; args) { ret = arg; } assert(ret=="b"); // passes return ret; } void main() { char[] s = bug874("b"); assert(s == "b"); // fails }
Comment #4 by clugdbug — 2009-10-30T02:16:21Z
Looks like this is just a D2 fix which didn't get transferred across to D1. PATCH (against DMD1 svn 227): expression.c, ForeachStatement::semantic, line 1380. // Declare value if (arg->storageClass & (STCout | STCref | STClazy)) error("no storage class for value %s", arg->ident->toChars()); Dsymbol *var; if (te) - { - if (e->type->toBasetype()->ty == Tfunction && - e->op == TOKvar) + { Type *tb = e->type->toBasetype(); + if ((tb->ty == Tfunction || tb->ty == Tsarray) && e->op == TOKvar) { VarExp *ve = (VarExp *)e; var = new AliasDeclaration(loc, arg->ident, ve->var); }
Comment #5 by leandro.lucarella — 2009-11-04T06:40:53Z
Comment #6 by bugzilla — 2009-11-06T11:32:29Z
Fixed dmd 1.051