diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 5e39b7671..4fcfd0f91 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -251,11 +251,14 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) if ((D->Flags & FD_FASTCALL) != 0 && D->ParamCount > 0) { /* Will use registers depending on the last param */ SymEntry* LastParam = D->SymTab->SymTail; - if (SizeOf (LastParam->Type) == 1) { + unsigned LastParamSize = CheckedSizeOf (LastParam->Type); + if (LastParamSize == 1) { *Use = REG_A; - } else { + } else if (LastParamSize == 2) { *Use = REG_AX; - } + } else { + *Use = REG_EAX; + } } else if ((D->Flags & FD_VARIADIC) != 0) { *Use = REG_Y; } else { diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 9d974e67f..01778b5f8 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -426,8 +426,7 @@ unsigned SizeOf (const type* T) switch (UnqualifiedType (T[0])) { case T_VOID: - Error ("Variable has unknown size"); - return 1; /* Return something that makes sense */ + return 0; /* Assume voids have size zero */ case T_SCHAR: case T_UCHAR: @@ -489,6 +488,38 @@ unsigned PSizeOf (const type* T) +unsigned CheckedSizeOf (const type* T) +/* Return the size of a data type. If the size is zero, emit an error and + * return some valid size instead (so the rest of the compiler doesn't have + * to work with invalid sizes). + */ +{ + unsigned Size = SizeOf (T); + if (Size == 0) { + Error ("Size of data type is unknown"); + Size = 1; + } + return Size; +} + + + +unsigned CheckedPSizeOf (const type* T) +/* Return the size of a data type that is pointed to by a pointer. If the + * size is zero, emit an error and return some valid size instead (so the + * rest of the compiler doesn't have to work with invalid sizes). + */ +{ + unsigned Size = PSizeOf (T); + if (Size == 0) { + Error ("Size of data type is unknown"); + Size = 1; + } + return Size; +} + + + unsigned TypeOf (const type* T) /* Get the code generator base type of the object */ { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index beabf2bd8..a750afff2 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -230,6 +230,17 @@ unsigned SizeOf (const type* Type); unsigned PSizeOf (const type* Type); /* Compute size of pointer object. */ +unsigned CheckedSizeOf (const type* T); +/* Return the size of a data type. If the size is zero, emit an error and + * return some valid size instead (so the rest of the compiler doesn't have + * to work with invalid sizes). + */ +unsigned CheckedPSizeOf (const type* T); +/* Return the size of a data type that is pointed to by a pointer. If the + * size is zero, emit an error and return some valid size instead (so the + * rest of the compiler doesn't have to work with invalid sizes). + */ + unsigned TypeOf (const type* Type); /* Get the code generator base type of the object */ diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0b516c956..c05322f2f 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -301,7 +301,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType) AddLocalSym (Decl.Ident, Decl.Type, SC_SFLD, (StructType == T_STRUCT)? Size : 0); /* Calculate offset of next field/size of the union */ - Offs = SizeOf (Decl.Type); + Offs = CheckedSizeOf (Decl.Type); if (StructType == T_STRUCT) { Size += Offs; } else { @@ -767,7 +767,7 @@ static FuncDesc* ParseFuncDecl (void) Offs = (F->Flags & FD_VARIADIC)? 1 : 0; Sym = GetSymTab()->SymTail; while (Sym) { - unsigned Size = SizeOf (Sym->Type); + unsigned Size = CheckedSizeOf (Sym->Type); Sym->V.Offs = Offs; Offs += Size; F->ParamSize += Size; @@ -1049,7 +1049,7 @@ static void ParseStructInit (type* Type) /* If there are struct fields left, reserve additional storage */ while (Entry) { - g_zerobytes (SizeOf (Entry->Type)); + g_zerobytes (CheckedSizeOf (Entry->Type)); Entry = Entry->NextSym; } } @@ -1128,7 +1128,7 @@ void ParseInit (type* T) if (Size == 0) { Encode (T + 1, Count); } else if (Count < Size) { - g_zerobytes ((Size - Count) * SizeOf (T + DECODE_SIZE + 1)); + g_zerobytes ((Size - Count) * CheckedSizeOf (T + DECODE_SIZE + 1)); } else if (Count > Size) { Error ("Too many initializers"); } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 62785b653..57d3ca89e 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -573,7 +573,7 @@ static unsigned FunctionParamList (FuncDesc* Func) if (FrameParams > 0 && (Func->Flags & FD_FASTCALL) != 0) { /* Last parameter is not pushed */ const SymEntry* LastParam = Func->SymTab->SymTail; - FrameSize -= SizeOf (LastParam->Type); + FrameSize -= CheckedSizeOf (LastParam->Type); --FrameParams; } @@ -632,7 +632,7 @@ static unsigned FunctionParamList (FuncDesc* Func) * use a special function that may optimize. */ CFlags = CF_NONE; - if (!Ellipsis && SizeOf (Param->Type) == 1) { + if (!Ellipsis && CheckedSizeOf (Param->Type) == 1) { CFlags = CF_FORCECHAR; } Flags = CF_NONE; @@ -1079,7 +1079,7 @@ static int arrayref (int k, ExprDesc* lval) if (IsClassPtr (tptr1)) { /* Scale the subscript value according to element size */ - lval2.ConstVal *= PSizeOf (tptr1); + lval2.ConstVal *= CheckedPSizeOf (tptr1); /* Remove code for lhs load */ RemoveCode (Mark1); @@ -1114,7 +1114,7 @@ static int arrayref (int k, ExprDesc* lval) lval2.Type = Indirect (tptr2); /* Scale the rhs value in the primary register */ - g_scale (TypeOf (tptr1), SizeOf (lval2.Type)); + g_scale (TypeOf (tptr1), CheckedSizeOf (lval2.Type)); /* */ lval->Type = lval2.Type; } else { @@ -1143,7 +1143,7 @@ static int arrayref (int k, ExprDesc* lval) * portion of the index (which is in (e)ax, so there's no further * action required). */ - g_scale (CF_INT, SizeOf (lval->Type)); + g_scale (CF_INT, CheckedSizeOf (lval->Type)); } else if (IsClassPtr (tptr2)) { @@ -1165,7 +1165,7 @@ static int arrayref (int k, ExprDesc* lval) } /* Scale it */ - g_scale (TypeOf (tptr1), SizeOf (lval2.Type)); + g_scale (TypeOf (tptr1), CheckedSizeOf (lval2.Type)); lval->Type = lval2.Type; } else { Error ("Cannot subscript"); @@ -1194,12 +1194,12 @@ static int arrayref (int k, ExprDesc* lval) (rflags & E_MGLOBAL) != 0 || /* Static array, or ... */ rflags == E_MLOCAL; /* Local array */ - if (ConstSubAddr && SizeOf (lval->Type) == 1) { + if (ConstSubAddr && CheckedSizeOf (lval->Type) == 1) { type* SavedType; /* Reverse the order of evaluation */ - unsigned flags = (SizeOf (lval2.Type) == 1)? CF_CHAR : CF_INT; + unsigned flags = (CheckedSizeOf (lval2.Type) == 1)? CF_CHAR : CF_INT; RemoveCode (Mark2); /* Get a pointer to the array into the primary. We have changed @@ -1414,7 +1414,7 @@ static void pre_incdec (ExprDesc* lval, void (*inc) (unsigned, unsigned long)) flags = TypeOf (lval->Type) | CF_FORCECHAR | CF_CONST; /* Get the increment value in bytes */ - val = (lval->Type [0] == T_PTR)? PSizeOf (lval->Type) : 1; + val = (lval->Type [0] == T_PTR)? CheckedPSizeOf (lval->Type) : 1; /* We're currently only able to handle some adressing modes */ if ((lval->Flags & E_MGLOBAL) == 0 && /* Global address? */ @@ -1502,7 +1502,7 @@ static void post_incdec (ExprDesc *lval, int k, void (*inc) (unsigned, unsigned /* If we have a pointer expression, increment by the size of the type */ if (lval->Type[0] == T_PTR) { - inc (flags | CF_CONST | CF_FORCECHAR, SizeOf (lval->Type + 1)); + inc (flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (lval->Type + 1)); } else { inc (flags | CF_CONST | CF_FORCECHAR, 1); } @@ -1587,8 +1587,8 @@ static int typecast (ExprDesc* lval) if (IsClassInt (Type)) { /* Get the current and new size of the value */ - unsigned OldSize = SizeOf (lval->Type); - unsigned NewSize = SizeOf (Type); + unsigned OldSize = CheckedSizeOf (lval->Type); + unsigned NewSize = CheckedSizeOf (Type); unsigned OldBits = OldSize * 8; unsigned NewBits = NewSize * 8; @@ -1720,13 +1720,13 @@ static int hie10 (ExprDesc* lval) if (istypeexpr ()) { type Type[MAXTYPELEN]; NextToken (); - lval->ConstVal = SizeOf (ParseType (Type)); + lval->ConstVal = CheckedSizeOf (ParseType (Type)); ConsumeRParen (); } else { /* Remember the output queue pointer */ CodeMark Mark = GetCodePos (); hie10 (lval); - lval->ConstVal = SizeOf (lval->Type); + lval->ConstVal = CheckedSizeOf (lval->Type); /* Remove any generated code */ RemoveCode (Mark); } @@ -2039,11 +2039,11 @@ static void parseadd (int k, ExprDesc* lval) /* Both expressions are constants. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - lval->ConstVal = lval->ConstVal + lval2.ConstVal * PSizeOf (lhst); + lval->ConstVal += lval2.ConstVal * CheckedPSizeOf (lhst); /* Result type is a pointer */ } else if (IsClassInt (lhst) && IsClassPtr (rhst)) { /* Left is int, right is pointer, must scale lhs */ - lval->ConstVal = lval->ConstVal * PSizeOf (rhst) + lval2.ConstVal; + lval->ConstVal = lval->ConstVal * CheckedPSizeOf (rhst) + lval2.ConstVal; /* Result type is a pointer */ lval->Type = lval2.Type; } else if (IsClassInt (lhst) && IsClassInt (rhst)) { @@ -2085,7 +2085,7 @@ static void parseadd (int k, ExprDesc* lval) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, PSizeOf (lhst)); + g_scale (CF_INT, CheckedPSizeOf (lhst)); /* Operate on pointers, result type is a pointer */ flags |= CF_PTR; /* Generate the code for the add */ @@ -2099,7 +2099,7 @@ static void parseadd (int k, ExprDesc* lval) } else if (IsClassInt (lhst) && IsClassPtr (rhst)) { /* Left is int, right is pointer, must scale lhs. */ - unsigned ScaleFactor = PSizeOf (rhst); + unsigned ScaleFactor = CheckedPSizeOf (rhst); /* Operate on pointers, result type is a pointer */ flags |= CF_PTR; @@ -2166,12 +2166,12 @@ static void parseadd (int k, ExprDesc* lval) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - lval2.ConstVal *= PSizeOf (lhst); + lval2.ConstVal *= CheckedPSizeOf (lhst); /* Operate on pointers, result type is a pointer */ flags = CF_PTR; } else if (IsClassInt (lhst) && IsClassPtr (rhst)) { /* Left is int, right is pointer, must scale lhs (ptr only) */ - g_scale (CF_INT | CF_CONST, PSizeOf (rhst)); + g_scale (CF_INT | CF_CONST, CheckedPSizeOf (rhst)); /* Operate on pointers, result type is a pointer */ flags = CF_PTR; lval->Type = lval2.Type; @@ -2198,14 +2198,14 @@ static void parseadd (int k, ExprDesc* lval) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, PSizeOf (lhst)); + g_scale (CF_INT, CheckedPSizeOf (lhst)); /* Operate on pointers, result type is a pointer */ flags = CF_PTR; } else if (IsClassInt (lhst) && IsClassPtr (rhst)) { /* Left is int, right is pointer, must scale lhs */ g_tosint (TypeOf (rhst)); /* Make sure, TOS is int */ g_swap (CF_INT); /* Swap TOS and primary */ - g_scale (CF_INT, PSizeOf (rhst)); + g_scale (CF_INT, CheckedPSizeOf (rhst)); /* Operate on pointers, result type is a pointer */ flags = CF_PTR; lval->Type = lval2.Type; @@ -2276,14 +2276,15 @@ static void parsesub (int k, ExprDesc* lval) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - lval->ConstVal -= lval2.ConstVal * PSizeOf (lhst); + lval->ConstVal -= lval2.ConstVal * CheckedPSizeOf (lhst); /* Operate on pointers, result type is a pointer */ } else if (IsClassPtr (lhst) && IsClassPtr (rhst)) { /* Left is pointer, right is pointer, must scale result */ if (TypeCmp (Indirect (lhst), Indirect (rhst)) < TC_QUAL_DIFF) { Error ("Incompatible pointer types"); } else { - lval->ConstVal = (lval->ConstVal - lval2.ConstVal) / PSizeOf (lhst); + lval->ConstVal = (lval->ConstVal - lval2.ConstVal) / + CheckedPSizeOf (lhst); } /* Operate on pointers, result type is an integer */ lval->Type = type_int; @@ -2310,7 +2311,7 @@ static void parsesub (int k, ExprDesc* lval) if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - lval2.ConstVal *= PSizeOf (lhst); + lval2.ConstVal *= CheckedPSizeOf (lhst); /* Operate on pointers, result type is a pointer */ flags = CF_PTR; } else if (IsClassPtr (lhst) && IsClassPtr (rhst)) { @@ -2318,7 +2319,7 @@ static void parsesub (int k, ExprDesc* lval) if (TypeCmp (Indirect (lhst), Indirect (rhst)) < TC_QUAL_DIFF) { Error ("Incompatible pointer types"); } else { - rscale = PSizeOf (lhst); + rscale = CheckedPSizeOf (lhst); } /* Operate on pointers, result type is an integer */ flags = CF_PTR; @@ -2353,7 +2354,7 @@ static void parsesub (int k, ExprDesc* lval) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, PSizeOf (lhst)); + g_scale (CF_INT, CheckedPSizeOf (lhst)); /* Operate on pointers, result type is a pointer */ flags = CF_PTR; } else if (IsClassPtr (lhst) && IsClassPtr (rhst)) { @@ -2361,7 +2362,7 @@ static void parsesub (int k, ExprDesc* lval) if (TypeCmp (Indirect (lhst), Indirect (rhst)) < TC_QUAL_DIFF) { Error ("Incompatible pointer types"); } else { - rscale = PSizeOf (lhst); + rscale = CheckedPSizeOf (lhst); } /* Operate on pointers, result type is an integer */ flags = CF_PTR; @@ -2848,13 +2849,13 @@ static void opeq (GenDesc* Gen, ExprDesc *lval, int k) } if (MustScale) { /* lhs is a pointer, scale rhs */ - lval2.ConstVal *= SizeOf (lval->Type+1); + lval2.ConstVal *= CheckedSizeOf (lval->Type+1); } /* If the lhs is character sized, the operation may be later done * with characters. */ - if (SizeOf (lval->Type) == 1) { + if (CheckedSizeOf (lval->Type) == 1) { flags |= CF_FORCECHAR; } @@ -2870,13 +2871,13 @@ static void opeq (GenDesc* Gen, ExprDesc *lval, int k) /* rhs is not constant and already in the primary register */ if (MustScale) { /* lhs is a pointer, scale rhs */ - g_scale (TypeOf (lval2.Type), SizeOf (lval->Type+1)); + g_scale (TypeOf (lval2.Type), CheckedSizeOf (lval->Type+1)); } /* If the lhs is character sized, the operation may be later done * with characters. */ - if (SizeOf (lval->Type) == 1) { + if (CheckedSizeOf (lval->Type) == 1) { flags |= CF_FORCECHAR; } @@ -2928,7 +2929,7 @@ static void addsubeq (GenDesc* Gen, ExprDesc *lval, int k) /* The resulting value is a constant. */ if (MustScale) { /* lhs is a pointer, scale rhs */ - lval2.ConstVal *= SizeOf (lval->Type+1); + lval2.ConstVal *= CheckedSizeOf (lval->Type+1); } rflags |= CF_CONST; lflags |= CF_CONST; @@ -2936,7 +2937,7 @@ static void addsubeq (GenDesc* Gen, ExprDesc *lval, int k) /* rhs is not constant and already in the primary register */ if (MustScale) { /* lhs is a pointer, scale rhs */ - g_scale (TypeOf (lval2.Type), SizeOf (lval->Type+1)); + g_scale (TypeOf (lval2.Type), CheckedSizeOf (lval->Type+1)); } } @@ -3027,7 +3028,7 @@ static void Assignment (ExprDesc* lval) } /* Load the size of the struct into the primary */ - g_getimmed (CF_INT | CF_UNSIGNED | CF_CONST, SizeOf (ltype), 0); + g_getimmed (CF_INT | CF_UNSIGNED | CF_CONST, CheckedSizeOf (ltype), 0); /* Call the memcpy function */ g_call (CF_FIXARGC, "memcpy", 4); @@ -3038,7 +3039,7 @@ static void Assignment (ExprDesc* lval) PushAddr (lval); /* No struct, setup flags for the load */ - flags = SizeOf (ltype) == 1? CF_FORCECHAR : CF_NONE; + flags = CheckedSizeOf (ltype) == 1? CF_FORCECHAR : CF_NONE; /* Get the expression on the right of the '=' into the primary */ if (evalexpr (flags, hie1, &lval2) == 0) { diff --git a/src/cc65/locals.c b/src/cc65/locals.c index f911af016..591cbb73a 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2000-2001 Ullrich von Bassewitz */ +/* (C) 2000-2002 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@cc65.org */ @@ -112,7 +112,7 @@ static int AllocRegVar (const SymEntry* Sym, const type* tarray) if (EnableRegVars) { /* Get the size of the variable */ - unsigned Size = SizeOf (tarray); + unsigned Size = CheckedSizeOf (tarray); /* Do we have space left? */ if (RegOffs >= Size) { @@ -417,7 +417,7 @@ void RestoreRegVars (int HaveResult) /* Check for more than one variable */ const SymEntry* Sym = RegSyms[I]; Offs = Sym->V.Offs; - Bytes = SizeOf (Sym->Type); + Bytes = CheckedSizeOf (Sym->Type); J = I+1; while (J < RegSymCount) { @@ -426,7 +426,7 @@ void RestoreRegVars (int HaveResult) const SymEntry* NextSym = RegSyms [J]; /* Get the size */ - int Size = SizeOf (NextSym->Type); + int Size = CheckedSizeOf (NextSym->Type); /* Adjacent variable? */ if (NextSym->V.Offs + Size != Offs) {