Skip to content

Commit

Permalink
Merge pull request #9072 from WalterBright/fix19473
Browse files Browse the repository at this point in the history
fix Issue 19473 - DMD Segfault on circular struct reference
  • Loading branch information
thewilsonator authored Dec 13, 2018
2 parents b191ad4 + 3d99269 commit 5aa95b5
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/dmd/aggregate.d
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ enum Sizeok : int
{
none, // size of aggregate is not yet able to compute
fwd, // size of aggregate is ready to compute
inProcess, // in the midst of computing the size
done, // size of aggregate is set correctly
}

Expand Down Expand Up @@ -77,7 +78,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
uint structsize; // size of struct
uint alignsize; // size of struct for alignment purposes
VarDeclarations fields; // VarDeclaration fields
Sizeok sizeok; // set when structsize contains valid data
Sizeok sizeok = Sizeok.none; // set when structsize contains valid data
Dsymbol deferred; // any deferred semantic2() or semantic3() symbol
bool isdeprecated; // true if deprecated

Expand Down
3 changes: 2 additions & 1 deletion src/dmd/aggregate.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ enum Sizeok
{
SIZEOKnone, // size of aggregate is not yet able to compute
SIZEOKfwd, // size of aggregate is ready to compute
SIZEOKdone // size of aggregate is set correctly
SIZEOKinProcess, // in the midst of computing the size
SIZEOKdone, // size of aggregate is set correctly
};

enum Baseok
Expand Down
9 changes: 9 additions & 0 deletions src/dmd/dstruct.d
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,12 @@ extern (C++) class StructDeclaration : AggregateDeclaration
//printf("StructDeclaration::finalizeSize() %s, sizeok = %d\n", toChars(), sizeok);
assert(sizeok != Sizeok.done);

if (sizeok == Sizeok.inProcess)
{
return;
}
sizeok = Sizeok.inProcess;

//printf("+StructDeclaration::finalizeSize() %s, fields.dim = %d, sizeok = %d\n", toChars(), fields.dim, sizeok);

fields.setDim(0); // workaround
Expand All @@ -363,7 +369,10 @@ extern (C++) class StructDeclaration : AggregateDeclaration
s.setFieldOffset(this, &offset, isunion);
}
if (type.ty == Terror)
{
errors = true;
return;
}

// 0 sized struct's are set to 1 byte
if (structsize == 0)
Expand Down
31 changes: 31 additions & 0 deletions test/fail_compilation/test19473.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* TEST_OUTPUT:
---
fail_compilation/test19473.d(14): Error: union `test19473.P` no size because of forward reference
---
*/

// https://issues.dlang.org/show_bug.cgi?id=19473

struct A {
P p;

struct UTpl() {
union {
P p;
}
}

alias U = UTpl!();
}

alias B = A.U;

struct C {
union D {
B b;
}
}

union P {
C.D p;
}

0 comments on commit 5aa95b5

Please sign in to comment.