Skip to content

Commit

Permalink
fix Issue 15455 - [REG v2.065] Compiler segfault for simple nested st…
Browse files Browse the repository at this point in the history
…ructure
  • Loading branch information
WalterBright authored and 9rnsr committed Mar 20, 2016
1 parent c134e0f commit 414e10b
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 10 deletions.
27 changes: 17 additions & 10 deletions src/argtypes.d
Expand Up @@ -18,7 +18,11 @@ import ddmd.visitor;
* This breaks a type down into 'simpler' types that can be passed to a function
* in registers, and returned in registers.
* It's highly platform dependent.
* Returning a tuple of zero length means the type cannot be passed/returned in registers.
* Params:
* t = type to break down
* Returns:
* tuple of types, each element can be passed in a register.
* A tuple of zero length means the type cannot be passed/returned in registers.
*/
extern (C++) TypeTuple toArgTypes(Type t)
{
Expand Down Expand Up @@ -173,10 +177,16 @@ extern (C++) TypeTuple toArgTypes(Type t)

/*************************************
* This merges two types into an 8byte type.
* Params:
* t1 = first type (can be null)
* t2 = second type (can be null)
* offset2 = offset of t2 from start of t1
* Returns:
* type that encompasses both t1 and t2, null if cannot be done
*/
static Type argtypemerge(Type t1, Type t2, uint offset2)
{
//printf("argtypemerge(%s, %s, %d)\n", t1 ? t1->toChars() : "", t2 ? t2->toChars() : "", offset2);
//printf("argtypemerge(%s, %s, %d)\n", t1 ? t1.toChars() : "", t2 ? t2.toChars() : "", offset2);
if (!t1)
{
assert(!t2 || offset2 == 0);
Expand Down Expand Up @@ -217,14 +227,9 @@ extern (C++) TypeTuple toArgTypes(Type t)
case 4:
t = Type.tint32;
break;
case 5:
case 6:
case 7:
case 8:
default:
t = Type.tint64;
break;
default:
assert(0);
}
}
return t;
Expand Down Expand Up @@ -270,7 +275,7 @@ extern (C++) TypeTuple toArgTypes(Type t)

override void visit(TypeStruct t)
{
//printf("TypeStruct::toArgTypes() %s\n", t->toChars());
//printf("TypeStruct.toArgTypes() %s\n", t.toChars());
if (!t.sym.isPOD() || t.sym.fields.dim == 0)
{
Lmemory:
Expand Down Expand Up @@ -331,7 +336,7 @@ extern (C++) TypeTuple toArgTypes(Type t)
for (size_t i = 0; i < t.sym.fields.dim; i++)
{
VarDeclaration f = t.sym.fields[i];
//printf("f->type = %s\n", f->type->toChars());
//printf(" [%d] %s f.type = %s\n", cast(int)i, f.toChars(), f.type.toChars());
TypeTuple tup = toArgTypes(f.type);
if (!tup)
goto Lmemory;
Expand Down Expand Up @@ -366,6 +371,8 @@ extern (C++) TypeTuple toArgTypes(Type t)
}
// First field in 8byte must be at start of 8byte
assert(t1 || f.offset == 0);
//printf("ft1 = %s\n", ft1 ? ft1.toChars() : "null");
//printf("ft2 = %s\n", ft2 ? ft2.toChars() : "null");
if (ft1)
{
t1 = argtypemerge(t1, ft1, f.offset);
Expand Down
46 changes: 46 additions & 0 deletions test/runnable/cppa.d
Expand Up @@ -1084,6 +1084,51 @@ void test15610()
c.f();
}

/******************************************/
// 15455

struct X6
{
ushort a;
ushort b;
ubyte c;
ubyte d;
}

static assert(X6.sizeof == 6);

struct X8
{
ushort a;
X6 b;
}

static assert(X8.sizeof == 8);

void test15455a(X8 s)
{
assert(s.a == 1);
assert(s.b.a == 2);
assert(s.b.b == 3);
assert(s.b.c == 4);
assert(s.b.d == 5);
}

extern (C++) void test15455b(X8 s);

void test15455()
{
X8 s;

s.a = 1;
s.b.a = 2;
s.b.b = 3;
s.b.c = 4;
s.b.d = 5;
test15455a(s);
test15455b(s);
}

/****************************************/

void main()
Expand Down Expand Up @@ -1123,6 +1168,7 @@ void main()
testeh3();
test15579();
test15610();
test15455();

printf("Success\n");
}
28 changes: 28 additions & 0 deletions test/runnable/extra-files/cppb.cpp
Expand Up @@ -695,4 +695,32 @@ void Derived2::f()
}

/******************************************/
// 15455

struct X6
{
unsigned short a;
unsigned short b;
unsigned char c;
unsigned char d;
};

struct X8
{
unsigned short a;
X6 b;
};

void test15455b(X8 s)
{
assert(sizeof(X6) == 6);
assert(sizeof(X8) == 8);
assert(s.a == 1);
assert(s.b.a == 2);
assert(s.b.b == 3);
assert(s.b.c == 4);
assert(s.b.d == 5);
}

/******************************************/

0 comments on commit 414e10b

Please sign in to comment.