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

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 874 - Bad codegen: wrong value variable in tuple foreach, D1 only
Summary: Bad codegen: wrong value variable in tuple foreach, D1 only
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: x86 All
: P2 normal
Assignee: No Owner
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
Reported: 2007年01月22日 22:12 UTC by Jarrett Billingsley
Modified: 2014年02月15日 13:12 UTC (History)
3 users (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description Jarrett Billingsley 2007年01月22日 22:12:26 UTC
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 Thomas Kühne 2007年02月23日 16:36:10 UTC
Added to DStress as
http://dstress.kuehne.cn/run/o/odd_bug_13_A.d 
Comment 2 Don 2009年08月12日 06:17:48 UTC
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 Don 2009年10月30日 01:53:50 UTC
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 Don 2009年10月30日 02:16:21 UTC
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 Leandro Lucarella 2009年11月04日 06:40:53 UTC
SVN commit: http://www.dsource.org/projects/dmd/changeset/236 
Comment 6 Walter Bright 2009年11月06日 11:32:29 UTC
Fixed dmd 1.051


AltStyle によって変換されたページ (->オリジナル) /