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:
parent
5f09200360
commit
997f0c119f
22
expression.c
22
expression.c
|
@ -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)
|
||||||
|
|
2
picoc.h
2
picoc.h
|
@ -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
4
type.c
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue