]> git.sur5r.net Git - cc65/commitdiff
Fixed problems with incomplete types (structs and arrays) that could cause
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 10 Mar 2002 20:44:58 +0000 (20:44 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 10 Mar 2002 20:44:58 +0000 (20:44 +0000)
internal compiler errors in several places.
An old cc65 extension (variables of type void) was broken and did no longer
work. Fixed that.

git-svn-id: svn://svn.cc65.org/cc65/trunk@1184 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codeinfo.c
src/cc65/datatype.c
src/cc65/datatype.h
src/cc65/declare.c
src/cc65/expr.c
src/cc65/locals.c

index 5e39b76710775b77047839a7fc9f43531b5e400a..4fcfd0f91de80de17bf6b66226838c734134549f 100644 (file)
@@ -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 {
index 9d974e67f759352596c290c0a7b5cbf628c5886c..01778b5f836fbff43504fd4979fd6326d623c141 100644 (file)
@@ -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 */
 {
index beabf2bd86067c40d1bbb34f3a9e9830584de56b..a750afff23368e3df1478de4a9fb8d0dfc69c88d 100644 (file)
@@ -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 */
 
index 0b516c95636c1574dc4aa5cfe09fedcf18482e33..c05322f2f74743a808e48d5dbce982fdf7e7b755 100644 (file)
@@ -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");
            }
index 62785b65326338bc052ae1ef5dc06ab0873f7f4a..57d3ca89e4b6ce85f2d4079926563a6af0308a8f 100644 (file)
@@ -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) {
index f911af01637d4ed26a97c04f1eaa443dcbd3e989..591cbb73a4c3ca9a1f1071366357dccc9e3e7770 100644 (file)
@@ -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) {