Skip to content

Commit 2093050

Browse files
author
Don Clugston
committed
6374 [CTFE] Cannot subscript using pointer to array
ptr[n] = x and y = ptr[n] need to be special cased, just as slice assignment is.
1 parent c8cfe94 commit 2093050

File tree

1 file changed

+48
-3
lines changed

1 file changed

+48
-3
lines changed

src/interpret.c

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2718,6 +2718,7 @@ Expression *copyLiteral(Expression *e)
27182718
{
27192719
e->error("Internal Compiler Error: CTFE literal %s", e->toChars());
27202720
assert(0);
2721+
return e;
27212722
}
27222723
}
27232724

@@ -3382,7 +3383,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
33823383
uinteger_t destarraylen = 0; // not for AAs
33833384

33843385
// Set the $ variable, and find the array literal to modify
3385-
if (ie->e1->type->toBasetype()->ty != Taarray)
3386+
if (ie->e1->type->toBasetype()->ty != Taarray && ie->e1->type->toBasetype()->ty != Tpointer)
33863387
{
33873388
Expression *oldval = ie->e1->interpret(istate);
33883389
if (oldval->op == TOKnull)
@@ -3417,11 +3418,28 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
34173418
StringExp *existingSE = NULL;
34183419
AssocArrayLiteralExp *existingAA = NULL;
34193420

3421+
Expression *aggregate = resolveReferences(ie->e1, istate->localThis);
3422+
34203423
// Set the index to modify (for non-AAs), and check that it is in range
34213424
int indexToModify = 0;
34223425
if (ie->e1->type->toBasetype()->ty != Taarray)
34233426
{
34243427
indexToModify = index->toInteger();
3428+
if (ie->e1->type->toBasetype()->ty == Tpointer)
3429+
{
3430+
dinteger_t ofs;
3431+
aggregate = aggregate->interpret(istate, ctfeNeedLvalue);
3432+
if (aggregate == EXP_CANT_INTERPRET)
3433+
return EXP_CANT_INTERPRET;
3434+
if (aggregate->op == TOKnull)
3435+
{
3436+
error("cannot index through null pointer %s", ie->e1->toChars());
3437+
return EXP_CANT_INTERPRET;
3438+
}
3439+
aggregate = getAggregateFromPointer(aggregate, &ofs);
3440+
indexToModify += ofs;
3441+
destarraylen = resolveArrayLength(aggregate);
3442+
}
34253443
if (indexToModify >= destarraylen)
34263444
{
34273445
error("array index %d is out of bounds [0..%d]", indexToModify,
@@ -3430,8 +3448,6 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
34303448
}
34313449
}
34323450

3433-
Expression *aggregate = resolveReferences(ie->e1, istate->localThis);
3434-
34353451
/* The only possible indexable LValue aggregates are array literals,
34363452
* slices of array literals, and AA literals.
34373453
*/
@@ -4216,7 +4232,36 @@ Expression *IndexExp::interpret(InterState *istate, CtfeGoal goal)
42164232
#if LOG
42174233
printf("IndexExp::interpret() %s\n", toChars());
42184234
#endif
4235+
if (this->e1->type->toBasetype()->ty == Tpointer)
4236+
{
4237+
// Indexing a pointer. Note that there is no $ in this case.
4238+
e1 = this->e1->interpret(istate);
4239+
if (e1 == EXP_CANT_INTERPRET)
4240+
return EXP_CANT_INTERPRET;
42194241

4242+
e2 = this->e2->interpret(istate);
4243+
if (e2 == EXP_CANT_INTERPRET)
4244+
return EXP_CANT_INTERPRET;
4245+
dinteger_t indx = e2->toInteger();
4246+
Expression *e;
4247+
dinteger_t ofs;
4248+
Expression *agg = getAggregateFromPointer(e1, &ofs);
4249+
if (agg->op == TOKnull)
4250+
{
4251+
error("cannot index null pointer %s", this->e1->toChars());
4252+
return EXP_CANT_INTERPRET;
4253+
}
4254+
assert(agg->op == TOKarrayliteral || agg->op == TOKstring);
4255+
dinteger_t len = ArrayLength(Type::tsize_t, agg)->toInteger();
4256+
Type *pointee = ((TypePointer *)agg->type)->next;
4257+
if ((indx + ofs) < 0 || (indx+ofs) > len)
4258+
{
4259+
error("pointer index [%jd] exceeds allocated memory block [0..%jd]",
4260+
indx+ofs, len);
4261+
return EXP_CANT_INTERPRET;
4262+
}
4263+
return Index(type, agg, new IntegerExp(loc, indx+ofs, Type::tsize_t));
4264+
}
42204265
e1 = this->e1->interpret(istate);
42214266
if (e1 == EXP_CANT_INTERPRET)
42224267
return EXP_CANT_INTERPRET;

0 commit comments

Comments
 (0)