Skip to content

Commit

Permalink
fix Issue 14649 - ICE on invalid array operation with string literals
Browse files Browse the repository at this point in the history
  • Loading branch information
9rnsr committed Jun 4, 2015
1 parent 6d40db6 commit daae6d7
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/cast.c
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,10 @@ MATCH implicitConvTo(Expression *e, Type *t)
result = MATCHconst;
}
}

// Enhancement 10724
if (tb->ty == Tpointer && e->e1->op == TOKstring)
e->e1->accept(this);
}
};

Expand Down
48 changes: 38 additions & 10 deletions src/optimize.c
Original file line number Diff line number Diff line change
Expand Up @@ -1060,19 +1060,33 @@ Expression *Expression_optimize(Expression *e, int result, bool keepLvalue)
{
// Convert slice of string literal into dynamic array
Type *t = e->e1->type->toBasetype();
if (t->nextOf())
ret = e->e1->castTo(NULL, t->nextOf()->arrayOf());
if (Type *tn = t->nextOf())
ret = e->e1->castTo(NULL, tn->arrayOf());
}
return;
}
e->e1 = fromConstInitializer(result, e->e1);
// We might know $ now
setLengthVarIfKnown(e->lengthVar, e->e1);
e->lwr = e->lwr->optimize(WANTvalue);
e->upr = e->upr->optimize(WANTvalue);
ret = Slice(e->type, e->e1, e->lwr, e->upr).copy();
if (CTFEExp::isCantExp(ret))
else
{
e->e1 = fromConstInitializer(result, e->e1);
// We might know $ now
setLengthVarIfKnown(e->lengthVar, e->e1);
e->lwr = e->lwr->optimize(WANTvalue);
e->upr = e->upr->optimize(WANTvalue);
ret = Slice(e->type, e->e1, e->lwr, e->upr).copy();
if (CTFEExp::isCantExp(ret))
ret = e;
}

// Bugzilla 14649: We need to leave the slice form so it might be
// a part of array operation.
// Assume that the backend codegen will handle the form `e[]`
// as an equal to `e` itself.
if (ret->op == TOKstring)
{
e->e1 = ret;
e->lwr = NULL;
e->upr = NULL;
ret = e;
}
//printf("-SliceExp::optimize() %s\n", ret->toChars());
}

Expand Down Expand Up @@ -1197,6 +1211,20 @@ Expression *Expression_optimize(Expression *e, int result, bool keepLvalue)
}
}

// optimize "str"[] -> "str"
if (e->e1->op == TOKslice)
{
SliceExp *se1 = (SliceExp *)e->e1;
if (se1->e1->op == TOKstring && !se1->lwr)
e->e1 = se1->e1;
}
if (e->e2->op == TOKslice)
{
SliceExp *se2 = (SliceExp *)e->e2;
if (se2->e1->op == TOKstring && !se2->lwr)
e->e2 = se2->e1;
}

ret = Cat(e->type, e->e1, e->e2).copy();
if (CTFEExp::isCantExp(ret))
ret = e;
Expand Down
18 changes: 18 additions & 0 deletions test/fail_compilation/fail_arrayop1.d
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,21 @@ void test11566()
int[] a;
a[] <<= 1;
}

/*
TEST_OUTPUT:
---
fail_compilation/fail_arrayop1.d(147): Error: invalid array operation a + b (possible missing [])
fail_compilation/fail_arrayop1.d(148): Error: invalid array operation x + y (possible missing [])
fail_compilation/fail_arrayop1.d(149): Error: invalid array operation "hel" + "lo." (possible missing [])
---
*/
void test14649()
{
char[] a, b, r;
string x, y;

r[] = a + b;
r[] = x + y;
r[] = "hel" + "lo.";
}
26 changes: 26 additions & 0 deletions test/runnable/arrayop.d
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,31 @@ void test13497()
assert(c2 == [6]);
}

/************************************************************************/
// 14649

void test14649()
{
char[] a = "abc".dup;
char[] b = [char(1), char(2), char(3)];
string x = "abc";
string y = [char(1), char(2), char(3)];
char[] r = new char[](3);

r[] = a[] + b[];
assert(r == "bdf");

r[] = x[] + y[];
assert(r == "bdf");

r[] = "hel"[] + "lo."[];
assert(r == [('h'+'l'), ('e'+'o'), ('l'+'.')]);

enum s = "abc";
r[] = s[0..3] + "def"[0..3];
assert(r == [('a'+'d'), ('b'+'e'), ('c'+'f')]);
}

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

int main()
Expand All @@ -866,6 +891,7 @@ int main()
test12250();
test12780();
test13497();
test14649();

printf("Success\n");
return 0;
Expand Down

0 comments on commit daae6d7

Please sign in to comment.