Skip to content

Commit

Permalink
fix Issue 14390 - ICE or bad "has forward references" error with circ…
Browse files Browse the repository at this point in the history
…ular class structure

Class instance size can be determined before the completion of class members semantic.
  • Loading branch information
9rnsr committed Apr 3, 2015
1 parent 0e5f690 commit 5346e25
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/aggregate.h
Expand Up @@ -47,6 +47,7 @@ enum Baseok
BASEOKnone, // base classes not computed yet
BASEOKin, // in process of resolving base classes
BASEOKdone, // all base classes are resolved
BASEOKsemanticdone, // all base classes semantic done
};

enum StructPOD
Expand Down
20 changes: 13 additions & 7 deletions src/class.c
Expand Up @@ -321,13 +321,10 @@ void ClassDeclaration::semantic(Scope *sc)
if (sc->linkage == LINKcpp)
cpp = true;
}
else if (symtab)
else if (symtab && !scx)
{
if (sizeok == SIZEOKdone || !scx)
{
semanticRun = PASSsemanticdone;
return;
}
semanticRun = PASSsemanticdone;
return;
}
semanticRun = PASSsemantic;

Expand Down Expand Up @@ -622,8 +619,10 @@ void ClassDeclaration::semantic(Scope *sc)
}
}

if (sizeok == SIZEOKnone)
if (baseok == BASEOKdone)
{
baseok = BASEOKsemanticdone;

// initialize vtbl
if (baseClass)
{
Expand Down Expand Up @@ -674,6 +673,10 @@ void ClassDeclaration::semantic(Scope *sc)
makeNested();
}

// it might be determined already, by AggregateDeclaration::size().
if (sizeok != SIZEOKdone)
sizeok = SIZEOKnone;

Scope *sc2 = sc->push(this);
//sc2->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STC_TYPECTOR | STCtls | STCgshared);
//sc2->stc |= storage_class & STC_TYPECTOR;
Expand Down Expand Up @@ -1493,7 +1496,10 @@ void InterfaceDeclaration::semantic(Scope *sc)
}
}

if (baseok == BASEOKdone)
{
baseok = BASEOKsemanticdone;

// initialize vtbl
if (vtblOffset())
vtbl.push(this); // leave room at vtbl[0] for classinfo
Expand Down
13 changes: 13 additions & 0 deletions test/compilable/testfwdref.d
Expand Up @@ -342,6 +342,19 @@ class E12984b(T) : D12984b!int
static assert(__traits(classInstanceSize, B12984b) == (void*).sizeof * 2 + int.sizeof);
static assert(__traits(classInstanceSize, C12984b) == (void*).sizeof * 2 + int.sizeof * 2);

/***************************************************/
// 14390

class B14390a { alias MyD = D14390a!int; }
class C14390a : B14390a { void f(int) {} }
class D14390a(T) { alias MyE = E14390a!float; }
class E14390a(T) : D14390a!int { void m() { auto c = new C14390a(); } }

class B14390b { alias MyD = D14390b!int; }
class C14390b : B14390b { static struct S {} }
class D14390b(T) { alias MyE = E14390b!float; }
class E14390b(T) : D14390b!int { void m() { auto c = new C14390b(); } }

/***************************************************/
// 13860

Expand Down

0 comments on commit 5346e25

Please sign in to comment.