Created attachment 746 [details] 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
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 }
(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.
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.
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()); }
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.
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; + } + }
http://www.dsource.org/projects/dmd/changeset/673