Bug 6473 – Stack overflow with struct destructor as default parameter

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-08-11T19:08:00Z
Last change time
2012-02-01T04:03:49Z
Keywords
ice, patch
Assigned to
nobody
Creator
hoganmeier

Comments

Comment #0 by hoganmeier — 2011-08-11T19:08:12Z
struct Eins { ~this() {} } struct Zwei { void build(Eins devices = Eins()) { } } $ gdb --batch -ex "run program.d" -ex "bt 10" dmd DMD v2.054 DEBUG Program received signal SIGSEGV, Segmentation fault. 0x00007ffff72e4893 in vfprintf () from /lib/x86_64-linux-gnu/libc.so.6 #0 0x00007ffff72e4893 in vfprintf () from /lib/x86_64-linux-gnu/libc.so.6 #1 0x00007ffff730af02 in vsnprintf () from /lib/x86_64-linux-gnu/libc.so.6 #2 0x00007ffff72efc4f in snprintf () from /lib/x86_64-linux-gnu/libc.so.6 #3 0x00000000004fa225 in Lexer::uniqueId (s=0x5b4aaa "__sl", num=8590) at lexer.c:2881 #4 0x00000000004fa277 in Lexer::uniqueId (s=0x5b4aaa "__sl") at lexer.c:2888 #5 0x00000000004a0204 in StructLiteralExp::semantic (this=0x1128b80, sc=0x1128a70) at expression.c:3648 #6 0x000000000047281d in VarDeclaration::semantic (this=0x1128890, sc=0x1128a70) at declaration.c:1280 #7 0x00000000004a4390 in DeclarationExp::semantic (this=0x1128990, sc=0x1128670) at expression.c:4910 #8 0x00000000004a66f5 in BinExp::semantic (this=0x1128a20, sc=0x1128670) at expression.c:5626 #9 0x00000000004a6881 in BinExp::semanticp (this=0x1128a20, sc=0x1128670) at expression.c:5646 build as a free function doesn't trigger it. Nor does a global 'Eins devices = Eins();'. btw, lexer.c(2876): Identifier *Lexer::uniqueId(const char *s, int num) { char buffer[32]; size_t slen = strlen(s); assert(slen + sizeof(num) * 3 + 1 <= sizeof(buffer)); sprintf(buffer, "%s%d", s, num); Why that sizeof(num) there? It's always 4. Why isn't snprintf(buffer, 32.... used?
Comment #1 by clugdbug — 2011-09-19T02:10:40Z
It's not a segfault, and it has nothing to do with Lexer::uniqueId. It's a stack overflow. It's also D2-only, because it requires a struct destructor. StructLiteralExp::semantic() sees that Eins has a destructor, so it rewrites it as Eins devices = (Eins tmp = Eins(), tmp); Then, it runs semantic on the comma expression it created. VarDeclaration::semantic on tmp calls StructLiteralExp::semantic, which again sees Eins has destructor, so it does an another rewrite. Eins devices = (Eins tmp = (Eins tmp2 = Eins(), tmp2), tmp);
Comment #2 by hoganmeier — 2011-10-18T05:01:06Z
Very interesting. Any idea how to solve it?
Comment #3 by k.hara.pg — 2011-12-22T01:26:55Z
Comment #4 by hoganmeier — 2012-02-01T04:03:49Z