Bug 21473 – DMD enters infinite loop

Status
RESOLVED
Resolution
WORKSFORME
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2020-12-11T19:32:24Z
Last change time
2022-03-25T11:23:19Z
Assigned to
No Owner
Creator
Jacob Carlborg
Depends on
21702

Comments

Comment #0 by doob — 2020-12-11T19:32:24Z
Compiling the following code with DMD 2.094.0 on macOS: import std.algorithm.searching; import std.stdio; import std.meta; import std.algorithm.sorting : sort; void main() { static immutable test = [ "ια"w, "ιά", "ιο", "ιό", "ιε", "ιέ", "ιυ", "ιύ", "ιι", "ιί", "ιω", "ιώ", "ιϊ", "ιΐ", "ιϋ", "ιΰ", "ιη", "ιή", "ιου", "ιού", "ιοι", "ιοί", "ιει", "ιεί", "ιαι", "ιαί", "ιυι", "ιυί", "ηα", "ηά", "ηο", "ηό", "ηε", "ηέ", "ηυ", "ηύ", "ηι", "ηί", "ηω", "ηώ", "ηϊ", "ηΐ", "ηϋ", "ηΰ", "ηη", "ηή", "ηου", "ηού", "ηοι", "ηοί", "ηει", "ηεί", "ηαι", "ηαί", "ηυι", "ηυί", "υα", "υά", "υο", "υό", "υε", "υέ", "υυ", "υύ", "υι", "υί", "υω", "υώ", "υϊ", "υΐ", "υϋ", "υΰ", "υη", "υή", "υου", "υού", "υοι", "υοί", "υει", "υεί", "υαι", "υαί", "υυι", "υυί" ].sort!`a.length > b.length`().release(); auto qaz = "οιιοιιοιιεεεείί"w.endsWith(aliasSeqOf!test); qaz.writeln; } Causes what might be an infinite loop. Eventually the compiler segfaults. This is the backtrace from running inside a debugger: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x7ffeef3ffff8) frame #0: 0x00000001001f0d35 dmd`TemplateInstance::isDiscardable() + 5 dmd`TemplateInstance::isDiscardable: -> 0x1001f0d35 <+5>: pushq %r12 0x1001f0d37 <+7>: pushq %rbx 0x1001f0d38 <+8>: movq %rdi, %r14 0x1001f0d3b <+11>: movq 0x120(%rdi), %rdi Target 0: (dmd) stopped. (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x7ffeef3ffff8) * frame #0: 0x00000001001f0d35 dmd`TemplateInstance::isDiscardable() + 5 frame #1: 0x0000000100018c99 dmd`TemplateInstance::needsCodegen() + 313 frame #174658: 0x00000001000193af dmd`TemplateInstance::needsCodegen() + 2127 frame #174659: 0x00000001000189da dmd`toObjFile::ToObjFile::visit(TemplateInstance*) + 42 frame #174660: 0x000000010003d28a dmd`genObjFile(Module*, bool) + 2186 frame #174661: 0x000000010012b226 dmd`_D3dmd4mars7tryMainFmPPxaKSQz7globals5ParamZi + 8438 frame #174662: 0x00000001001362df dmd`_Dmain + 31 frame #174663: 0x00000001004df2b8 dmd`_D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv + 120 frame #174664: 0x00000001004df09f dmd`_d_run_main2 + 399 frame #174665: 0x00000001004deefd dmd`_d_run_main + 141 frame #174666: 0x00007fff6dc91cc9 libdyld.dylib`start + 1 frame #174667: 0x00007fff6dc91cc9 libdyld.dylib`start + 1 dmd`TemplateInstance::needsCodegen() is repeated over 174000 times. I've reduced the stacktrace above to save space. Originally reported here for Windows: https://forum.dlang.org/post/[email protected].
Comment #1 by boris2.9 — 2020-12-11T22:57:59Z
There are two issues here, the first is in phobos that somewhere in the pipeline generates a ridiculous amount of template instances. Second is the recursive nature of 'TemplateInstance::needsCodegen()' that overflows the stack when there are too many instances of a particular template, this is the same bug as issue 18026 and the only way to fix it is to refactor 'needsCodegen' function. You can reproduce it with this simple piece of code: --------------- struct S() {} static foreach (i; 0..180000) { mixin("S!() s", i, ";"); } --------------- The number of iterations can vary, for example using a non-optimized DMD build I only need '90000' to crash. (my stack size is 8MB)
Comment #2 by n8sh.secondary — 2021-03-12T17:08:11Z
https://github.com/dlang/phobos/pull/7847 solves the problem of Phobos performing a crazy amount of template expansion for this code.
Comment #3 by johan_forsberg_86 — 2021-04-24T16:27:02Z
Does https://github.com/dlang/phobos/pull/7847 solve this issue? If so, update the status.
Comment #4 by razvan.nitu1305 — 2022-03-25T11:23:19Z
I can't reproduce this with the latest version of the compiler. Closing as WORKSFORME. Please reopen if I am missing something.