D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 6473 - Stack overflow with struct destructor as default parameter
Summary: Stack overflow with struct destructor as default parameter
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 major
Assignee: No Owner
URL:
Keywords: ice, patch
Depends on:
Blocks:
 
Reported: 2011-08-11 19:08 UTC by Trass3r
Modified: 2012-02-01 04:03 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Trass3r 2011-08-11 19:08:12 UTC
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 Don 2011-09-19 02:10:40 UTC
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 Trass3r 2011-10-18 05:01:06 UTC
Very interesting. Any idea how to solve it?