Skip to content

Commit

Permalink
Merge pull request #5387 from WalterBright/fix15618
Browse files Browse the repository at this point in the history
fix Issue 15618 - [REG-master] Class member layout has been changed, …
  • Loading branch information
yebblies committed Feb 1, 2016
2 parents 5665dc7 + 5bebb65 commit 9c90f94
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 3 deletions.
7 changes: 6 additions & 1 deletion src/dclass.d
Expand Up @@ -1162,7 +1162,8 @@ public:
}

// Add vptr's for any interfaces implemented by this class
structsize += setBaseInterfaceOffsets(structsize);
if (cpp)
structsize += setBaseInterfaceOffsets(structsize);

uint offset = structsize;
for (size_t i = 0; i < members.dim; i++)
Expand All @@ -1173,6 +1174,10 @@ public:
if (sizeok == SIZEOKfwd)
return;

// Add vptr's for any interfaces implemented by this class
if (!cpp)
structsize += setBaseInterfaceOffsets(structsize);

sizeok = SIZEOKdone;

// Calculate fields[i].overlapped
Expand Down
52 changes: 50 additions & 2 deletions src/todt.c
Expand Up @@ -678,7 +678,7 @@ dt_t **membersToDt(AggregateDeclaration *ad, dt_t **pdt,
else
offset = 0;

if (cd)
if (cd && cd->cpp)
{
// Interface vptr initializations
toSymbol(cd); // define csym
Expand Down Expand Up @@ -766,6 +766,30 @@ dt_t **membersToDt(AggregateDeclaration *ad, dt_t **pdt,
offset = vd->offset + vd->type->size();
}

if (cd && !cd->cpp)
{
// Interface vptr initializations
toSymbol(cd); // define csym

for (size_t i = 0; i < cd->vtblInterfaces->dim; i++)
{
BaseClass *b = (*cd->vtblInterfaces)[i];
for (ClassDeclaration *cd2 = concreteType; 1; cd2 = cd2->baseClass)
{
assert(cd2);
unsigned csymoffset = baseVtblOffset(cd2, b);
if (csymoffset != ~0)
{
if (offset < b->offset)
pdt = dtnzeros(pdt, b->offset - offset);
pdt = dtxoff(pdt, toSymbol(cd2), csymoffset);
break;
}
}
offset = b->offset + Target::ptrsize;
}
}

if (offset < ad->structsize)
pdt = dtnzeros(pdt, ad->structsize - offset);

Expand Down Expand Up @@ -804,7 +828,7 @@ dt_t **membersToDt(AggregateDeclaration *ad, dt_t **pdt,
else
offset = 0;

if (cd)
if (cd && cd->cpp)
{
// Interface vptr initializations
toSymbol(cd); // define csym
Expand Down Expand Up @@ -871,6 +895,30 @@ dt_t **membersToDt(AggregateDeclaration *ad, dt_t **pdt,
offset = vd->offset + vd->type->size();
}

if (cd && !cd->cpp)
{
// Interface vptr initializations
toSymbol(cd); // define csym

for (size_t i = 0; i < cd->vtblInterfaces->dim; i++)
{
BaseClass *b = (*cd->vtblInterfaces)[i];
for (ClassDeclaration *cd2 = concreteType; 1; cd2 = cd2->baseClass)
{
assert(cd2);
unsigned csymoffset = baseVtblOffset(cd2, b);
if (csymoffset != ~0)
{
if (offset < b->offset)
pdt = dtnzeros(pdt, b->offset - offset);
pdt = dtxoff(pdt, toSymbol(cd2), csymoffset);
break;
}
}
offset = b->offset + Target::ptrsize;
}
}

if (offset < ad->structsize)
pdt = dtnzeros(pdt, ad->structsize - offset);

Expand Down
19 changes: 19 additions & 0 deletions test/compilable/test15618.d
@@ -0,0 +1,19 @@
class Base
{
~this() {}
size_t x = 4;
}

interface Interface
{
int Method();
}

class Derived : Base, Interface
{
size_t y = 5;
int Method() { return 3; }
}

static assert(Derived.x.offsetof == (void*).sizeof * 2);
static assert(Derived.y.offsetof == (void*).sizeof * 3);

0 comments on commit 9c90f94

Please sign in to comment.