Bug 18260 – ICE on template this parameter and alias this

Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-01-18T09:00:33Z
Last change time
2020-03-21T03:56:32Z
Keywords
ice
Assigned to
No Owner
Creator
Simen Kjaeraas

Comments

Comment #0 by simen.kjaras — 2018-01-18T09:00:33Z
The following code causes DMD to hang: struct R { int[] arr; alias get this; R get(this This)() { return R.init; } } unittest { const(R) b = const(R).init; } As far as my testing shows, every line is necessary, and arr must be a dynamic array. Changing get() to assert(false) instead of return, removes the bug.
Comment #1 by andrei — 2018-01-18T22:18:30Z
There is a workaround to this: struct R { int[] arr; alias get this; R get(this This)() { return R.init; } R get(this This)() const { return R.init; } } unittest { const(R) b = const(R).init; }
Comment #2 by andrei — 2018-01-18T22:20:15Z
A better workaround: struct R { int[] arr; alias get this; This get(this This)() { return This.init; } } unittest { const(R) b = const(R).init; } I suspect the problem is an infinite recursion during semantic checking.
Comment #3 by simen.kjaras — 2018-01-19T08:04:35Z
Slightly different version where the given workarounds don't work: struct R(T) { // Used 'auto' here, but 'This' or 'R!(const int)' gives same behavior. // Marking the method const or immutable likewise has no effect. auto get(this This)() { return R!(const int).init; } alias get this; } unittest { R!int a; R!(const int) b = a; } Note that the array is no longer needed. Interestingly, adding pragma(msg, This) inside get() provides no output.
Comment #4 by simen.kjaras — 2018-02-21T07:34:55Z
This seems flaky. The example in comment #3 compiles under 2.078.3, but the first example still causes DMD to freeze.
Comment #5 by greensunny12 — 2018-03-29T03:01:50Z
> but the first example still causes DMD to freeze. Here's a stack trace - it looks like compare_overload runs into an endless recursion: --- 0x00005555559cf3de in rt.util.array._enforceNoOverlap(const(char[]), ulong, ulong, const(ulong)) () #0 0x00005555559cf3de in rt.util.array._enforceNoOverlap(const(char[]), ulong, ulong, const(ulong)) () #1 0x00005555559c98ef in _d_arraycopy () #2 0x00005555559c3166 in _d_newclass (ci=0x555555ab4860 <ClassInfo for dmd.dsymbol.ScopeDsymbol>) at dmd/root/rmem.d:210 #3 0x00005555557f2adc in TemplateDeclaration::deduceFunctionTemplateMatch(TemplateInstance*, Scope*, FuncDeclaration*&, Type*, Array<Expression*>*) (this=0x7ffff7e9f7d0, ti=0x7ffff510e330, sc=0x7ffff69f8f70, fd=@0x7fffff7ff960: 0x7ffff7e9f470, tthis=0x7ffff7e9fb20, fargs=0x0) at dmd/dtemplate.d:1118 #4 0x00005555557f7048 in int dmd.dtemplate.functionResolve(dmd.declaration.Match*, dmd.dsymbol.Dsymbol, dmd.globals.Loc, dmd.dscope.Scope*, dmd.root.array.Array!(dmd.root.rootobject.RootObject).Array*, dmd.mtype.Type, dmd.root.array.Array!(dmd.expression.Expression).Array*, const(char)**).applyTemplate(dmd.dtemplate.TemplateDeclaration) (this=0x7fffff7ffb50, td=0x7ffff7e9f7d0) at dmd/dtemplate.d:2690 #5 0x00005555557f7500 in int dmd.dtemplate.functionResolve(dmd.declaration.Match*, dmd.dsymbol.Dsymbol, dmd.globals.Loc, dmd.dscope.Scope*, dmd.root.array.Array!(dmd.root.rootobject.RootObject).Array*, dmd.mtype.Type, dmd.root.array.Array!(dmd.expression.Expression).Array*, const(char)**).__lambda11(dmd.dsymbol.Dsymbol) (this=0x7fffff7ffb50, s=0x7ffff7e9f7d0) at dmd/dtemplate.d:2797 #6 0x000055555583bc34 in int dmd.func.overloadApply(dmd.dsymbol.Dsymbol, int delegate(dmd.dsymbol.Dsymbol), dmd.dscope.Scope*) (sc=0x7ffff69f8f70, dg=..., fstart=0x7ffff7e9f7d0) at dmd/func.d:2414 #7 0x00005555557f5e21 in void dmd.dtemplate.functionResolve(dmd.declaration.Match*, dmd.dsymbol.Dsymbol, dmd.globals.Loc, dmd.dscope.Scope*, dmd.root.array.Array!(dmd.root.rootobject.RootObject).Array*, dmd.mtype.Type, dmd.root.array.Array!(dmd.expression.Expression).Array*, const(char)**) (pMessage=0x7fffff7ffbb0, fargs=0x0, tthis=0x7ffff7e9fb20, tiargs=0x0, sc=0x7ffff69f8f70, loc=..., dstart=0x7ffff7e9f7d0, m=0x7fffff7ffb90) at dmd/dtemplate.d:2799 #8 0x000055555583bfff in resolveFuncCall(Loc const&, Scope*, Dsymbol*, Array<RootObject*>*, Type*, Array<Expression*>*, int) (loc=..., sc=0x7ffff69f8f70, s=0x7ffff7e9f7d0, tiargs=0x0, tthis=0x7ffff7e9fb20, fargs=0x0, flags=0) at dmd/func.d:2575 #9 0x0000555555821b86 in ExpressionSemanticVisitor::visit(CallExp*) (this=0x7fffff800788, exp=0x7ffff510e2e0) at dmd/expressionsem.d:3142 #10 0x00005555558144ae in CallExp::accept(Visitor*) (this=0x7ffff510e2e0, v=0x7fffff800788) at dmd/expression.d:5607 #11 0x000055555583461f in expressionSemantic(Expression*, Scope*) (e=0x7ffff510e2e0, sc=0x7ffff69f8f70) at dmd/expressionsem.d:9367 #12 0x0000555555819509 in dmd.expression.Expression dmd.expressionsem.resolvePropertiesX(dmd.dscope.Scope*, dmd.expression.Expression, dmd.expression.Expression) (e2=0x0, e1=0x7ffff510d7d0, sc=0x7ffff69f8f70) at dmd/expressionsem.d:253 #13 0x00005555558198a7 in resolveProperties(Scope*, Expression*) (sc=0x7ffff69f8f70, e=0x7ffff510d7d0) at dmd/expressionsem.d:329 #14 0x000055555583457d in dmd.expression.Expression dmd.expressionsem.binSemanticProp(dmd.expression.BinExp, dmd.dscope.Scope*) (sc=0x7ffff69f8f70, e=0x555555f54b40) at dmd/expressionsem.d:9352 #15 0x000055555583320e in ExpressionSemanticVisitor::visit(EqualExp*) (this=0x7fffff800d18, exp=0x555555f54b40) at dmd/expressionsem.d:8900 #16 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f54b40, v=0x7fffff800d18) at dmd/expression.d:6981 #17 0x000055555583461f in expressionSemantic(Expression*, Scope*) (e=0x555555f54b40, sc=0x7ffff69f8f70) at dmd/expressionsem.d:9367 #18 0x000055555583440c in dmd.expression.Expression dmd.expressionsem.trySemantic(dmd.expression.Expression, dmd.dscope.Scope*) (sc=0x7ffff69f8f70, exp=0x555555f54b40) at dmd/expressionsem.d:9294 #19 0x000055555588bd8c in dmd.expression.Expression dmd.opover.compare_overload(dmd.expression.BinExp, dmd.dscope.Scope*, dmd.identifier.Identifier) (id=0x7ffff7e9d3c0, sc=0x7ffff69f8f70, e=0x555555f547d0) at dmd/opover.d:1666 #20 0x000055555588a171 in op_overload::OpOverload::visit(EqualExp*) (this=0x7fffff8012a0, e=0x555555f547d0) at dmd/opover.d:1175 #21 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f547d0, v=0x7fffff8012a0) at dmd/expression.d:6981 #22 0x000055555588797d in op_overload(Expression*, Scope*) (e=0x555555f547d0, sc=0x7ffff69f8f70) at dmd/opover.d:1536 #23 0x000055555580d551 in Expression::op_overload(Scope*) (this=0x555555f547d0, sc=0x7ffff69f8f70) at dmd/expression.d:2516 #24 0x0000555555833435 in ExpressionSemanticVisitor::visit(EqualExp*) (this=0x7fffff801508, exp=0x555555f547d0) at dmd/expressionsem.d:8966 #25 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f547d0, v=0x7fffff801508) at dmd/expression.d:6981 #26 0x000055555583461f in expressionSemantic(Expression*, Scope*) (e=0x555555f547d0, sc=0x7ffff69f8f70) at dmd/expressionsem.d:9367 #27 0x000055555583440c in dmd.expression.Expression dmd.expressionsem.trySemantic(dmd.expression.Expression, dmd.dscope.Scope*) (sc=0x7ffff69f8f70, exp=0x555555f547d0) at dmd/expressionsem.d:9294 #28 0x000055555588bd8c in dmd.expression.Expression dmd.opover.compare_overload(dmd.expression.BinExp, dmd.dscope.Scope*, dmd.identifier.Identifier) (id=0x7ffff7e9d3c0, sc=0x7ffff69f8f70, e=0x555555f54460) at dmd/opover.d:1666 #29 0x000055555588a171 in op_overload::OpOverload::visit(EqualExp*) (this=0x7fffff801a90, e=0x555555f54460) at dmd/opover.d:1175 #30 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f54460, v=0x7fffff801a90) at dmd/expression.d:6981 #31 0x000055555588797d in op_overload(Expression*, Scope*) (e=0x555555f54460, sc=0x7ffff69f8f70) at dmd/opover.d:1536 #32 0x000055555580d551 in Expression::op_overload(Scope*) (this=0x555555f54460, sc=0x7ffff69f8f70) at dmd/expression.d:2516 #33 0x0000555555833435 in ExpressionSemanticVisitor::visit(EqualExp*) (this=0x7fffff801cf8, exp=0x555555f54460) at dmd/expressionsem.d:8966 #34 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f54460, v=0x7fffff801cf8) at dmd/expression.d:6981 #35 0x000055555583461f in expressionSemantic(Expression*, Scope*) (e=0x555555f54460, sc=0x7ffff69f8f70) at dmd/expressionsem.d:9367 #36 0x000055555583440c in dmd.expression.Expression dmd.expressionsem.trySemantic(dmd.expression.Expression, dmd.dscope.Scope*) (sc=0x7ffff69f8f70, exp=0x555555f54460) at dmd/expressionsem.d:9294 #37 0x000055555588bd8c in dmd.expression.Expression dmd.opover.compare_overload(dmd.expression.BinExp, dmd.dscope.Scope*, dmd.identifier.Identifier) (id=0x7ffff7e9d3c0, sc=0x7ffff69f8f70, e=0x555555f540f0) at dmd/opover.d:1666 #38 0x000055555588a171 in op_overload::OpOverload::visit(EqualExp*) (this=0x7fffff802280, e=0x555555f540f0) at dmd/opover.d:1175 #39 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f540f0, v=0x7fffff802280) at dmd/expression.d:6981 #40 0x000055555588797d in op_overload(Expression*, Scope*) (e=0x555555f540f0, sc=0x7ffff69f8f70) at dmd/opover.d:1536 #41 0x000055555580d551 in Expression::op_overload(Scope*) (this=0x555555f540f0, sc=0x7ffff69f8f70) at dmd/expression.d:2516 #42 0x0000555555833435 in ExpressionSemanticVisitor::visit(EqualExp*) (this=0x7fffff8024e8, exp=0x555555f540f0) at dmd/expressionsem.d:8966 #43 0x0000555555816dd2 in EqualExp::accept(Visitor*) (this=0x555555f540f0, v=0x7fffff8024e8) at dmd/expression.d:6981 --- The log says the same: --- BinExp::compare_overload(id = opEquals) p == q BinExp::compare_overload(id = opEquals) p.get() == q BinExp::compare_overload(id = opEquals) p.get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get().get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get().get().get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get().get().get().get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get().get().get().get().get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get().get().get().get().get().get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get().get().get().get().get().get().get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get().get().get().get().get().get().get().get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get().get().get().get().get().get().get().get().get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get().get().get().get().get().get().get().get().get().get().get() == q BinExp::compare_overload(id = opEquals) p.get().get().get().get().get().get().get().get().get().get().get().get().get().get() == q ---
Comment #6 by b2.temp — 2019-07-16T20:27:07Z
fixed since 2.086