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

View file

@ -311,7 +311,7 @@ int ExpressionParseInt(struct ParseState *Parser);
/* type.c */ /* type.c */
void TypeInit(); void TypeInit();
void TypeCleanup(); void TypeCleanup();
int TypeSize(struct ValueType *Typ, int ArraySize); int TypeSize(struct ValueType *Typ, int ArraySize, int Compact);
int TypeSizeValue(struct Value *Val); int TypeSizeValue(struct Value *Val);
int TypeStackSizeValue(struct Value *Val); int TypeStackSizeValue(struct Value *Val);
int TypeLastAccessibleOffset(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 */ /* 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 */ return sizeof(int); /* allow some extra room for type extension to int */
else if (Typ->Base != TypeArray) else if (Typ->Base != TypeArray)
return Typ->Sizeof; return Typ->Sizeof;

View file

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