Skip to content

Commit

Permalink
Merge pull request #4162 from WalterBright/pointerdiff
Browse files Browse the repository at this point in the history
CTFE: pointerDifference() now returns UnionExp
  • Loading branch information
9rnsr committed Nov 24, 2014
2 parents 2db1617 + 5efe77e commit ae83653
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/ctfe.h
Expand Up @@ -201,7 +201,7 @@ Expression *getAggregateFromPointer(Expression *e, dinteger_t *ofs);
bool pointToSameMemoryBlock(Expression *agg1, Expression *agg2);

// return e1 - e2 as an integer, or error if not possible
Expression *pointerDifference(Loc loc, Type *type, Expression *e1, Expression *e2);
UnionExp pointerDifference(Loc loc, Type *type, Expression *e1, Expression *e2);

/// Return 1 if true, 0 if false
/// -1 if comparison is illegal because they point to non-comparable memory blocks
Expand Down
23 changes: 14 additions & 9 deletions src/ctfeexpr.c
Expand Up @@ -655,35 +655,40 @@ bool pointToSameMemoryBlock(Expression *agg1, Expression *agg2)
}

// return e1 - e2 as an integer, or error if not possible
Expression *pointerDifference(Loc loc, Type *type, Expression *e1, Expression *e2)
UnionExp pointerDifference(Loc loc, Type *type, Expression *e1, Expression *e2)
{
UnionExp ue;
dinteger_t ofs1, ofs2;
Expression *agg1 = getAggregateFromPointer(e1, &ofs1);
Expression *agg2 = getAggregateFromPointer(e2, &ofs2);
if (agg1 == agg2)
{
Type *pointee = ((TypePointer *)agg1->type)->next;
dinteger_t sz = pointee->size();
return new IntegerExp(loc, (ofs1 - ofs2) * sz, type);
new(&ue) IntegerExp(loc, (ofs1 - ofs2) * sz, type);
}
if (agg1->op == TOKstring && agg2->op == TOKstring)
else if (agg1->op == TOKstring && agg2->op == TOKstring)
{
if (((StringExp *)agg1)->string == ((StringExp *)agg2)->string)
{
Type *pointee = ((TypePointer *)agg1->type)->next;
dinteger_t sz = pointee->size();
return new IntegerExp(loc, (ofs1 - ofs2) * sz, type);
new(&ue) IntegerExp(loc, (ofs1 - ofs2) * sz, type);
}
}
else if (agg1->op == TOKsymoff && agg2->op == TOKsymoff &&
((SymOffExp *)agg1)->var == ((SymOffExp *)agg2)->var)
{
return new IntegerExp(loc, ofs1 - ofs2, type);
new(&ue) IntegerExp(loc, ofs1 - ofs2, type);
}
else
{
error(loc, "%s - %s cannot be interpreted at compile time: cannot subtract "
"pointers to two different memory blocks",
e1->toChars(), e2->toChars());
new(&ue) CTFEExp(TOKcantexp);
}
error(loc, "%s - %s cannot be interpreted at compile time: cannot subtract "
"pointers to two different memory blocks",
e1->toChars(), e2->toChars());
return CTFEExp::cantexp;
return ue;
}

// Return eptr op e2, where eptr is a pointer, e2 is an integer,
Expand Down
2 changes: 1 addition & 1 deletion src/interpret.c
Expand Up @@ -3239,7 +3239,7 @@ class Interpreter : public Visitor
result = e2;
return;
}
result = pointerDifference(e->loc, e->type, e1, e2);
result = pointerDifference(e->loc, e->type, e1, e2).copy();
return;
}
if (e->e1->type->ty == Tpointer && e->e2->type->isintegral())
Expand Down

0 comments on commit ae83653

Please sign in to comment.