Skip to content

Commit

Permalink
fix Issue 14682 - Incorrect interpretation of ~ []
Browse files Browse the repository at this point in the history
CatExp should check whether array literal operands can fit to opposite side type.
  • Loading branch information
9rnsr committed Jun 13, 2015
1 parent fbb6e2a commit 4d5c653
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/expression.c
Expand Up @@ -12410,16 +12410,26 @@ Expression *CatExp::semantic(Scope *sc)

if (tb1next && tb2next &&
(tb1next->implicitConvTo(tb2next) >= MATCHconst ||
tb2next->implicitConvTo(tb1next) >= MATCHconst)
tb2next->implicitConvTo(tb1next) >= MATCHconst ||
e1->op == TOKarrayliteral && e1->implicitConvTo(tb2) ||
e2->op == TOKarrayliteral && e2->implicitConvTo(tb1)
)
)
{
/* Here to avoid the case of:
/* Bugzilla 9248: Here to avoid the case of:
* void*[] a = [cast(void*)1];
* void*[] b = [cast(void*)2];
* a ~ b;
* becoming:
* a ~ [cast(void*)b];
*/

/* Bugzilla 14682: Also to avoid the case of:
* int[][] a;
* a ~ [];
* becoming:
* a ~ cast(int[])[];
*/
}
else if ((tb1->ty == Tsarray || tb1->ty == Tarray) &&
e2->implicitConvTo(tb1next) >= MATCHconvert &&
Expand Down
76 changes: 76 additions & 0 deletions test/runnable/test42.d
Expand Up @@ -5412,6 +5412,7 @@ void test9171()
}

/***************************************************/
// 9248

void test9248()
{
Expand All @@ -5421,6 +5422,79 @@ void test9248()
assert(c == [cast(void*)1, cast(void*)2]);
}

/***************************************************/
// 14682

void test14682a()
{
// operands
int[] a1;
int[][] a2;
int[][][] a3;
int[][][][] a4;

// results
int[] r1w = []; assert(r1w.length == 0);
int[][] r2w = []; assert(r2w.length == 0);
int[][][] r3w = []; assert(r3w.length == 0);
int[][][][] r4w = []; assert(r4w.length == 0);
// ----
int[][] r2x = [[]]; assert(r2x.length == 1 && r2x[0].length == 0);
int[][][] r3x = [[]]; assert(r3x.length == 1 && r3x[0].length == 0);
int[][][][] r4x = [[]]; assert(r4x.length == 1 && r4x[0].length == 0);
// ----
int[][][] r3y = [[[]]]; assert(r3y.length == 1 && r3y[0].length == 1 && r3y[0][0].length == 0);
int[][][][] r4y = [[[]]]; assert(r4y.length == 1 && r4y[0].length == 1 && r4y[0][0].length == 0);
// ----
int[][][][] r4z = [[[[]]]]; assert(r4z.length == 1 && r4z[0].length == 1 && r4z[0][0].length == 1 && r4z[0][0][0].length == 0);

// ArrayLiteralExp conforms to the type of LHS.
{ auto x = a1 ~ [] ; static assert(is(typeof(x) == typeof(a1))); assert(x == r1w); } // no ambiguity
{ auto x = a2 ~ [] ; static assert(is(typeof(x) == typeof(a2))); assert(x == r2w); } // fix <- ambiguity
{ auto x = a3 ~ [] ; static assert(is(typeof(x) == typeof(a3))); assert(x == r3w); } // fix <- ambiguity
{ auto x = a4 ~ [] ; static assert(is(typeof(x) == typeof(a4))); assert(x == r4w); } // fix <- ambiguity
// ----
//{ auto x = a1 ~ [[]] ; } // (see test14682b)
{ auto x = a2 ~ [[]] ; static assert(is(typeof(x) == typeof(a2))); assert(x == r2x); } // no ambiguity
{ auto x = a3 ~ [[]] ; static assert(is(typeof(x) == typeof(a3))); assert(x == r3x); } // fix <- ambiguity
{ auto x = a4 ~ [[]] ; static assert(is(typeof(x) == typeof(a4))); assert(x == r4x); } // fix <- ambiguity
// ----
static assert(!__traits(compiles, { auto x = a1 ~ [[[]]] ; }));
//{ auto x = a2 ~ [[[]]] ; } // (see test14682b)
{ auto x = a3 ~ [[[]]] ; static assert(is(typeof(x) == typeof(a3))); assert(x == r3y); } // no ambiguity
{ auto x = a4 ~ [[[]]] ; static assert(is(typeof(x) == typeof(a4))); assert(x == r4y); } // fix <- ambiguity
// ----
static assert(!__traits(compiles, { auto x = a1 ~ [[[[]]]]; }));
static assert(!__traits(compiles, { auto x = a2 ~ [[[[]]]]; }));
//{ auto x = a3 ~ [[[[]]]]; } // (see test14682b)
{ auto x = a4 ~ [[[[]]]]; static assert(is(typeof(x) == typeof(a4))); assert(x == r4z); } // no ambiguity

// ArrayLiteralExp conforms to the type of RHS.
{ auto x = [] ~ a1; static assert(is(typeof(x) == typeof(a1))); assert(x == r1w); } // no ambiguity
{ auto x = [] ~ a2; static assert(is(typeof(x) == typeof(a2))); assert(x == r2w); } // fix <- ambiguity
{ auto x = [] ~ a3; static assert(is(typeof(x) == typeof(a3))); assert(x == r3w); } // fix <- ambiguity
{ auto x = [] ~ a4; static assert(is(typeof(x) == typeof(a4))); assert(x == r4w); } // fix <- ambiguity
// ----
//{ auto x = [[]] ~ a1; } // (see test14682b)
{ auto x = [[]] ~ a2; static assert(is(typeof(x) == typeof(a2))); assert(x == r2x); } // no ambiguity
{ auto x = [[]] ~ a3; static assert(is(typeof(x) == typeof(a3))); assert(x == r3x); } // fix <- ambiguity
{ auto x = [[]] ~ a4; static assert(is(typeof(x) == typeof(a4))); assert(x == r4x); } // fix <- ambiguity
// ----
static assert(!__traits(compiles, { auto x = [[[]]] ~ a1; }));
//{ auto x = [[[]]] ~ a2; } // (see test14682b)
{ auto x = [[[]]] ~ a3; static assert(is(typeof(x) == typeof(a3))); assert(x == r3y); } // no ambiguity
{ auto x = [[[]]] ~ a4; static assert(is(typeof(x) == typeof(a4))); assert(x == r4y); } // fix <- ambiguity
// ----
static assert(!__traits(compiles, { auto x = [[[[]]]] ~ a1; }));
static assert(!__traits(compiles, { auto x = [[[[]]]] ~ a2; }));
//{ auto x = [[[[]]]] ~ a3; } // (see test14682b)
{ auto x = [[[[]]]] ~ a4; static assert(is(typeof(x) == typeof(a4))); assert(x == r4z); } // no ambiguity
}

void test14682b()
{
}

/***************************************************/
// 9739

Expand Down Expand Up @@ -6151,6 +6225,8 @@ int main()
test8796();
test9171();
test9248();
test14682a();
test14682b();
test9739();
testdbl_to_ulong();
testdbl_to_uint();
Expand Down

0 comments on commit 4d5c653

Please sign in to comment.