Fixed a char * arithmetic bug

git-svn-id: http://picoc.googlecode.com/svn/trunk@273 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-04-29 03:24:15 +00:00
parent 5f09200360
commit 997f0c119f
4 changed files with 16 additions and 14 deletions

View file

@ -341,7 +341,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
else if (TopValue->Typ->Base == TypePointer)
{
/* pointer prefix arithmetic */
int Size = TypeSize(TopValue->Typ->FromType, 0);
int Size = TypeSize(TopValue->Typ->FromType, 0, TRUE);
int OrigOffset = TopValue->Val->Pointer.Offset;
struct Value *StackValue;
@ -400,8 +400,8 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
else if (TopValue->Typ->Base == TypePointer)
{
/* pointer postfix arithmetic */
int Size = TypeSize(TopValue->Typ->FromType, 0);
int OrigOffset = TopValue->Val->Pointer.Offset;
int Size = TypeSize(TopValue->Typ->FromType, 0, TRUE);
struct PointerValue OrigPointer = TopValue->Val->Pointer;
struct Value *StackValue;
if (TopValue->Val->Pointer.Segment == NULL)
@ -410,9 +410,6 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
if (!TopValue->IsLValue)
ProgramFail(Parser, "can't assign to this");
StackValue = ExpressionStackPushValueByType(Parser, StackTop, TopValue->Typ);
StackValue->Val->Pointer = TopValue->Val->Pointer;
switch (Op)
{
case TokenIncrement: TopValue->Val->Pointer.Offset += Size; break;
@ -421,8 +418,13 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
}
/* check pointer bounds */
if (TopValue->Val->Pointer.Offset < 0 || TopValue->Val->Pointer.Offset > TypeLastAccessibleOffset(TopValue->Val->Pointer.Segment))
TopValue->Val->Pointer.Offset = OrigOffset;
if (TopValue->Val->Pointer.Offset < 0)
TopValue->Val->Pointer.Offset = 0;
else if (TopValue->Val->Pointer.Offset > TypeLastAccessibleOffset(TopValue->Val->Pointer.Segment))
TopValue->Val->Pointer.Offset = TypeLastAccessibleOffset(TopValue->Val->Pointer.Segment);
StackValue = ExpressionStackPushValueByType(Parser, StackTop, TopValue->Typ);
StackValue->Val->Pointer = OrigPointer;
}
else
ProgramFail(Parser, "invalid operation");
@ -461,7 +463,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
/* make the array element result */
// XXX - need to handle char array access
Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)(BottomValue->Val->Array.Data + TypeSize(BottomValue->Typ->FromType, 0) * ArrayIndex), BottomValue->IsLValue, BottomValue->LValueFrom);
Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)(BottomValue->Val->Array.Data + TypeSize(BottomValue->Typ->FromType, 0, FALSE) * ArrayIndex), BottomValue->IsLValue, BottomValue->LValueFrom);
ExpressionStackPushValueNode(Parser, StackTop, Result);
}
else if (IS_INTEGER_COERCIBLE(TopValue) && IS_INTEGER_COERCIBLE(BottomValue))
@ -567,7 +569,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
else if (Op == TokenPlus || Op == TokenMinus)
{
/* pointer arithmetic */
int Size = TypeSize(BottomValue->Typ->FromType, 0);
int Size = TypeSize(BottomValue->Typ->FromType, 0, TRUE);
Pointer = BottomValue->Val->Pointer;
if (Pointer.Segment == NULL)

View file

@ -311,7 +311,7 @@ int ExpressionParseInt(struct ParseState *Parser);
/* type.c */
void TypeInit();
void TypeCleanup();
int TypeSize(struct ValueType *Typ, int ArraySize);
int TypeSize(struct ValueType *Typ, int ArraySize, int Compact);
int TypeSizeValue(struct Value *Val);
int TypeStackSizeValue(struct Value *Val);
int TypeLastAccessibleOffset(struct Value *Val);

4
type.c
View file

@ -86,9 +86,9 @@ int TypeLastAccessibleOffset(struct Value *Val)
}
/* memory used by a variable given its type and array size */
int TypeSize(struct ValueType *Typ, int ArraySize)
int TypeSize(struct ValueType *Typ, int ArraySize, int Compact)
{
if (Typ->Base == TypeChar)
if (Typ->Base == TypeChar && !Compact)
return sizeof(int); /* allow some extra room for type extension to int */
else if (Typ->Base != TypeArray)
return Typ->Sizeof;

View file

@ -101,7 +101,7 @@ struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize,
/* allocate a value given its type */
struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct ValueType *Typ, int IsLValue, struct Value *LValueFrom)
{
int Size = TypeSize(Typ, Typ->ArraySize);
int Size = TypeSize(Typ, Typ->ArraySize, FALSE);
struct Value *NewValue = VariableAllocValueAndData(Parser, Size, IsLValue, LValueFrom, FALSE);
assert(Size > 0 || Typ == &VoidType);
NewValue->Typ = Typ;