2206 – unnamed template mixin of class inside function or class has incorrect classinfo and mangleof

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 2206 - unnamed template mixin of class inside function or class has incorrect classinfo and mangleof
Summary: unnamed template mixin of class inside function or class has incorrect classi...
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: x86 Linux
: P2 normal
Assignee: Walter Bright
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
Reported: 2008年07月08日 14:16 UTC by Christian Kamm
Modified: 2014年02月24日 15:32 UTC (History)
0 users

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 Christian Kamm 2008年07月08日 14:16:52 UTC
Test:
--
template T() {
 class C {}
}
void main()
{
 mixin T!(); // using a named mixin here fixes it
 pragma(msg, T!().C.mangleof);
 pragma(msg, C.mangleof); // incorrectly outputs the same as above
 assert(T!().C.classinfo !is C.classinfo); // fails
 assert(T!().C.mangleof != C.mangleof); // fails
}
--
The types of T!().C and main.C are clearly different as the nested one carries an additional context pointer. This means that allocation relying on classinfo.init.length should be wrong too.
In the frontend the types are initially different and only merged into a single type during semantic. To be specific, Type::mangle unifies them as toDecoBuffer yields the same result for both.
Maybe this could be fixed by adding a TemplateMixin::mangle overload. This frontend bug causes some template-mixin related bugs in LLVMDC that seem to be worked around somehow in DMD.
Comment 1 Christian Kamm 2008年07月08日 14:37:13 UTC
To illustrate the resulting problem with class allocation:
--
import std.stdio;
class D {}
template T() {
 class C { this() { } }
}
void main()
{
 mixin T!();
 // all print 8
 writefln(T!().C.classinfo.init.length);
 writefln(C.classinfo.init.length);
 writefln(D.classinfo.init.length);
 auto c = new C; // segfault in _d_newclass
}
Comment 2 Christian Kamm 2008年07月09日 09:58:58 UTC
Adding the following override for TemplateMixin::mangle seems to have fixed the issue in LLVMDC:
--
char *TemplateMixin::mangle()
{
 OutBuffer buf;
 char *id;
#if 0
 printf("TemplateMixin::mangle() %s", toChars());
 if (parent)
 printf(" parent = %s %s", parent->kind(), parent->toChars());
 printf("\n");
#endif
 id = ident ? ident->toChars() : toChars();
// use parent instead of tempdecl->parent here
 if (parent)
 {
	char *p = parent->mangle();
	if (p[0] == '_' && p[1] == 'D')
	 p += 2;
	buf.writestring(p);
 }
 buf.printf("%"PRIuSIZE"%s", strlen(id), id);
 id = buf.toChars();
 buf.data = NULL;
 //printf("TemplateMixin::mangle() %s = %s\n", toChars(), id);
 return id;
}
--
Comment 3 Walter Bright 2010年12月04日 21:23:55 UTC
http://www.dsource.org/projects/dmd/changeset/777 


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