Created attachment 746
Code that fails
DMD fails to compile the attached code, printing "Error: cannot create
associative array T[string]" before crashing.
Error message printed by GDB:
Program received signal SIGSEGV, Segmentation fault.
0x0817f8b7 in TemplateInstance::semantic (this=0x953b418, sc=0x0, fargs=0x0)
at template.c:3554
3554 tinst = sc->tinst;
Backtrace:
#0 0x0817f8b7 in TemplateInstance::semantic (this=0x953b418, sc=0x0,
fargs=0x0) at template.c:3554
#1 0x0818028a in TemplateInstance::semantic (this=0x953b418, sc=0x0)
at template.c:3524
#2 0x081384b6 in TypeAArray::getImpl (this=0x82121e0) at mtype.c:3976
#3 0x0813ffa1 in TypeStruct::implicitConvTo (this=0x820df50, to=0x82121e0)
at mtype.c:6942
#4 0x0817be83 in Type::deduceType (this=0x820df50, sc=0x939b448,
tparam=0x82121e0, parameters=0x82120d0, dedtypes=0xffffc458)
at template.c:1881
#5 0x0817c4a1 in TypeStruct::deduceType (this=0x820df50, sc=0x939b448,
tparam=0x82121e0, parameters=0x82120d0, dedtypes=0xffffc458)
at template.c:2412
#6 0x08180e6d in TemplateDeclaration::deduceFunctionTemplateMatch (
this=0x8212e80, sc=0x9206218, loc=..., targsi=0x0, ethis=0x94dd5b0,
fargs=0x94dd600, dedargs=0xffffc600) at template.c:1109
#7 0x08181767 in TemplateDeclaration::deduceFunctionTemplate (this=0x8210f08,
sc=0x9206218, loc=..., targsi=0x0, ethis=0x94dd5b0, fargs=0x94dd600,
flags=0) at template.c:1470
#8 0x080efb8d in CallExp::semantic (this=0x94dd628, sc=0x9206218)
at expression.c:6929
#9 0x080e4fca in AssignExp::semantic (this=0x8208a98, sc=0x9206218)
at expression.c:8876
#10 0x08168368 in ExpStatement::semantic (this=0x8208ac0, sc=0x9206218)
at statement.c:245
#11 0x0816a7a1 in CompoundStatement::semantic (this=0x82091b8, sc=0x9206218)
at statement.c:464
#12 0x080f871b in FuncDeclaration::semantic3 (this=0x8207350, sc=0x9202ba8)
at func.c:1213
#13 0x0812c23d in Module::semantic3 (this=0x8206848) at module.c:830
#14 0x0812aafe in main (argc=6, argv=0x81fcde0) at mars.c:1174
Comment #1 by briancschott — 2010-09-05T19:29:53Z
Here's the code that fails:
The second opIndexAssign is written this way because of bug 2972.
module testcase;
struct SomeStruct
{
void opIndexAssign(T)(T[string] value, string key)
if(is(T : string) || is(T : int))
{
}
void opIndexAssign(T)(SomeStruct value, string key) if(is(T : SomeStruct))
{
}
}
void main(string[] args)
{
auto t = SomeStruct();
t["test"] = ["key": "value", "otherKey": "otherValue"];
auto k = SomeStruct();
t["fails"] = k;
// Error: cannot create associative array T[string]
// Segmentation fault
}
Comment #2 by briancschott — 2010-09-05T19:34:48Z
(In reply to comment #1)
That should have been:
void opIndexAssign(T)(T value, string key) if(is(T : SomeStruct))
{
}
But the error is the same either way. Bugzilla needs an edit button.
Comment #3 by clugdbug — 2010-09-06T23:56:32Z
Reduced test case:
----------
struct Struct4826 {}
void bug4826(T)(T[string] value) {}
void test4826()
{
bug4826(Struct4826());
}
----
This is closely related to bug 3996. The patch for bug 3996 removes the segfault, leaving only a useless error message with no line number, followed by a sensible error message with line number.
Comment #4 by clugdbug — 2010-09-07T00:04:26Z
Actually even with the patch for bug 3996, I found a test case which still segfaults:
------------
struct Struct4826 { }
void bug4826b(T)(int[int] value) {}
void test4826b()
{
bug4826b(Struct4826());
}
Comment #5 by clugdbug — 2010-09-07T13:47:50Z
The segfault should be turned into an ICE by adding an extra assert into
TypeAArray::getImpl(), in mtype.c 3967.
+ assert(ti->inst || sc);
ti->semantic(sc);
ti->semantic2(sc);
ti->semantic3(sc);
The problem is, that the template instance needs a scope (sc), but the scope is never set, so it remains NULL, causing a segfault when it is first used. I don't know how to solve this. I'm not even sure of what the scope should be.
Comment #6 by clugdbug — 2010-09-08T03:56:59Z
The original test case, and the one in comment 4, have slightly different causes. In comment 4, the problem is that AssociativeArray!() needs a scope, so that it can be instantiated. This is fixed by in the template.c patch. I believe that 'sc' is a correct scope, but I'm not certain.
The original test case is fixed by the patch to mtype.c. It's just error suppression.
Finally, I have a third test case which didn't even work on 2.040. This compiles when both patches are in place.
====================
void bug4826c(T)(int[int] value, T x) {}
void test4826c()
{
AssociativeArray!(int, int) z;
bug4826c(z,1);
}
====================
// Type::deduceType(), template.c line 1920
if (ty != tparam->ty)
+ {
+ // Can't instantiate AssociativeArray!() without a scope
+ if (tparam->ty == Taarray && !((TypeAArray*)tparam)->sc)
+ ((TypeAArray*)tparam)->sc = sc;
return implicitConvTo(tparam);
+ }
// goto Lnomatch;
if (nextOf())
return nextOf()->deduceType(sc, tparam->nextOf(), parameters, dedtypes);
Lexact:
return MATCHexact;
--------------
Also: mtype.c, line 7000.
MATCH TypeStruct::implicitConvTo(Type *to)
{ MATCH m;
//printf("TypeStruct::implicitConvTo(%s => %s)\n", toChars(), to->toChars());
if (to->ty == Taarray)
+ {
+ // If there is an error instantiating AssociativeArray!(), it shouldn't
+ // be reported -- it just means implicit conversion is impossible.
+ ++global.gag;
+ int errs = global.errors;
to = ((TypeAArray*)to)->getImpl()->type;
+ --global.gag;
+ if (errs != global.errors)
+ { global.errors = errs;
+ return MATCHnomatch;
+ }
+ }