Skip to content

Commit

Permalink
Merge pull request #2183 from klickverbot/structliteralexp-tochars
Browse files Browse the repository at this point in the history
Avoid infinite recursion on StructLiteralExp::toChars().
  • Loading branch information
9rnsr committed Jun 17, 2013
2 parents ee5a1de + cd0d899 commit a97521d
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/expression.c
Expand Up @@ -4691,7 +4691,21 @@ void StructLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring(sd->toChars());
buf->writeByte('(');
argsToCBuffer(buf, elements, hgs);

// CTFE can generate struct literals that contain an AddrExp pointing
// to themselves, need to avoid infinite recursion:
// struct S { this(int){ this.s = &this; } S* s; }
// const foo = new S(0);
if (stageflags & stageToCBuffer)
buf->writestring("<recursion>");
else
{
int old = stageflags;
stageflags |= stageToCBuffer;
argsToCBuffer(buf, elements, hgs);
stageflags = old;
}

buf->writeByte(')');
}

Expand Down
2 changes: 2 additions & 0 deletions src/expression.h
Expand Up @@ -526,6 +526,8 @@ class AssocArrayLiteralExp : public Expression
#define stageApply 0x8
//inlineScan is running
#define stageInlineScan 0x10
// toCBuffer is running
#define stageToCBuffer 0x20

class StructLiteralExp : public Expression
{
Expand Down
1 change: 1 addition & 0 deletions test/runnable/interpret.d
Expand Up @@ -3044,6 +3044,7 @@ const t109c = new Test109C();

struct Test109S { this(int){ this.s = &this; } Test109S* s; }
const t109s = new Test109S(0);
pragma(msg, t109s); // Make sure there is no infinite recursion.

void test109()
{
Expand Down

0 comments on commit a97521d

Please sign in to comment.