diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index e6d1e4526..d565551ea 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -49,21 +49,6 @@ -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Map a generator function and its attributes to a token */ -typedef struct GenDesc { - token_t Tok; /* Token to map to */ - unsigned Flags; /* Flags for generator function */ - void (*Func) (unsigned, unsigned long); /* Generator func */ -} GenDesc; - - - /*****************************************************************************/ /* Code */ /*****************************************************************************/ diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 85c9bd5a4..d1f78098d 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -218,14 +218,16 @@ static void Parse (void) ** void types in ISO modes. */ if (Size == 0) { - if (!IsTypeVoid (Decl.Type)) { + if (!IsEmptiableObjectType (Decl.Type)) { if (!IsTypeArray (Decl.Type)) { /* Size is unknown and not an array */ - Error ("Variable '%s' has unknown size", Decl.Ident); + Error ("Cannot initialize variable '%s' of unknown size", Decl.Ident); } } else if (IS_Get (&Standard) != STD_CC65) { /* We cannot declare variables of type void */ - Error ("Illegal type for variable '%s'", Decl.Ident); + Error ("Illegal type '%s' for variable '%s'", + GetFullTypeName (Decl.Type), + Decl.Ident); } } @@ -253,7 +255,7 @@ static void Parse (void) /* We cannot declare variables of type void */ Error ("Illegal type for variable '%s'", Decl.Ident); Entry->Flags &= ~(SC_STORAGE | SC_DEF); - } else if (Size == 0 && SymIsDef (Entry)) { + } else if (Size == 0 && SymIsDef (Entry) && !IsEmptiableObjectType (Decl.Type)) { /* Size is unknown. Is it an array? */ if (!IsTypeArray (Decl.Type)) { Error ("Variable '%s' has unknown size", Decl.Ident); diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index e43af238e..6d9afa403 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -805,7 +805,11 @@ unsigned CheckedSizeOf (const Type* T) { unsigned Size = SizeOf (T); if (Size == 0) { - Error ("Size of type '%s' is unknown", GetFullTypeName (T)); + if (HasUnknownSize (T + 1)) { + Error ("Size of type '%s' is unknown", GetFullTypeName (T)); + } else { + Error ("Size of type '%s' is 0", GetFullTypeName (T)); + } Size = SIZEOF_CHAR; /* Don't return zero */ } return Size; @@ -821,7 +825,11 @@ unsigned CheckedPSizeOf (const Type* T) { unsigned Size = PSizeOf (T); if (Size == 0) { - Error ("Size of type '%s' is unknown", GetFullTypeName (T + 1)); + if (HasUnknownSize (T + 1)) { + Error ("Pointer to type '%s' of unknown size", GetFullTypeName (T + 1)); + } else { + Error ("Pointer to type '%s' of 0 size", GetFullTypeName (T + 1)); + } Size = SIZEOF_CHAR; /* Don't return zero */ } return Size; @@ -999,6 +1007,25 @@ const Type* PtrConversion (const Type* T) +const Type* StdConversion (const Type* T) +/* If the type is a function, convert it to pointer to function. If the +** expression is an array, convert it to pointer to first element. If the +** type is an integer, do integeral promotion. Otherwise return T. +*/ +{ + if (IsTypeFunc (T)) { + return AddressOf (T); + } else if (IsTypeArray (T)) { + return AddressOf (GetElementType (T)); + } else if (IsClassInt (T)) { + return IntPromotion (T); + } else { + return T; + } +} + + + const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index c60023944..e8ba7b6c0 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -368,6 +368,12 @@ const Type* PtrConversion (const Type* T); ** return T. */ +const Type* StdConversion (const Type* T); +/* If the type is a function, convert it to pointer to function. If the +** expression is an array, convert it to pointer to first element. If the +** type is an integer, do integeral promotion. Otherwise return T. +*/ + const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0275e61a3..9c12741ec 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -48,13 +48,6 @@ -/* Map a generator function and its attributes to a token */ -typedef struct GenDesc { - token_t Tok; /* Token to map to */ - unsigned Flags; /* Flags for generator function */ - void (*Func) (unsigned, unsigned long); /* Generator func */ -} GenDesc; - /* Descriptors for the operations */ static GenDesc GenPASGN = { TOK_PLUS_ASSIGN, GEN_NOPUSH, g_add }; static GenDesc GenSASGN = { TOK_MINUS_ASSIGN, GEN_NOPUSH, g_sub }; @@ -243,7 +236,7 @@ static const GenDesc* FindGen (token_t Tok, const GenDesc* Table) /* Find a token in a generator table */ { while (Table->Tok != TOK_INVALID) { - if (Table->Tok == Tok) { + if ((token_t)Table->Tok == Tok) { return Table; } ++Table; @@ -772,9 +765,10 @@ static unsigned FunctionArgList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) } else { /* No prototype available. Convert array to "pointer to first - ** element", and function to "pointer to function". + ** element", function to "pointer to function" and do integral + ** promotion if necessary. */ - Expr.Type = PtrConversion (Expr.Type); + TypeConversion (&Expr, StdConversion (Expr.Type)); } @@ -1133,7 +1127,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = NewPointerTo (type_void); + E->Type = type_void_p; NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1952,7 +1946,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = NewPointerTo (Expr->Type); + Expr->Type = AddressOf (Expr->Type); break; case TOK_SIZEOF: @@ -2271,9 +2265,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ Tok = CurTok.Tok; NextToken (); - /* If lhs is a function, convert it to pointer to function */ + /* If lhs is a function, convert it to the address of the function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = NewPointerTo (Expr->Type); + Expr->Type = AddressOf (Expr->Type); } /* Get the lhs on stack */ @@ -2293,9 +2287,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* Get the right hand side */ MarkedExprWithCheck (hienext, &Expr2); - /* If rhs is a function, convert it to pointer to function */ + /* If rhs is a function, convert it to the address of the function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = NewPointerTo (Expr2.Type); + Expr2.Type = AddressOf (Expr2.Type); } /* Check for a numeric constant expression */ @@ -3069,7 +3063,7 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) Error ("Invalid operands for binary operator '+'"); } else { /* Array and function types must be converted to pointer types */ - Expr->Type = PtrConversion (Expr->Type); + Expr->Type = StdConversion (Expr->Type); } } @@ -3348,7 +3342,7 @@ static void parsesub (ExprDesc* Expr) } /* Result type is either a pointer or an integer */ - Expr->Type = PtrConversion (Expr->Type); + Expr->Type = StdConversion (Expr->Type); /* Condition code not set */ ED_MarkAsUntested (Expr); diff --git a/src/cc65/expr.h b/src/cc65/expr.h index 841edcb62..abdf8ab0d 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -26,13 +26,20 @@ #define SQP_KEEP_NONE 0x00 #define SQP_KEEP_TEST 0x01U #define SQP_KEEP_EAX 0x02U -#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */ +#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */ /* Generator attributes */ #define GEN_NOPUSH 0x01 /* Don't push lhs */ #define GEN_COMM 0x02 /* Operator is commutative */ #define GEN_NOFUNC 0x04 /* Not allowed for function pointers */ +/* Map a generator function and its attributes to a token */ +typedef struct GenDesc { + long Tok; /* Token to map to */ + unsigned Flags; /* Flags for generator function */ + void (*Func) (unsigned, unsigned long); /* Generator func */ +} GenDesc; + /*****************************************************************************/ diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index 3d7b7c384..7d0ace004 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -93,8 +93,7 @@ int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr) int ED_IsIndExpr (const ExprDesc* Expr) /* Check if the expression is a reference to its value */ { - return (Expr->Flags & E_ADDRESS_OF) == 0 && - !ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr); + return (Expr->Flags & E_ADDRESS_OF) == 0 && !ED_IsLocNone (Expr); } #endif @@ -282,7 +281,7 @@ ExprDesc* ED_AddrExpr (ExprDesc* Expr) case E_LOC_EXPR: Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE); - Expr->Flags |= E_LOC_PRIMARY | E_RTYPE_RVAL; + Expr->Flags |= E_ADDRESS_OF | E_LOC_PRIMARY | E_RTYPE_RVAL; break; default: diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 13eb36e5e..f2b66ee56 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -493,8 +493,7 @@ INLINE int ED_IsAddrExpr (const ExprDesc* Expr) INLINE int ED_IsIndExpr (const ExprDesc* Expr) /* Check if the expression is a reference to its value */ { - return (Expr->Flags & E_ADDRESS_OF) == 0 && - !ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr); + return (Expr->Flags & E_ADDRESS_OF) == 0 && !ED_IsLocNone (Expr); } #else int ED_IsIndExpr (const ExprDesc* Expr); diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 4b7f8e279..c5badc1b3 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -92,6 +92,7 @@ static void LoadAddress (unsigned Flags, ExprDesc* Expr) g_leasp (Expr->IVal); break; + case E_LOC_PRIMARY: case E_LOC_EXPR: if (Expr->IVal != 0) { /* We have an expression in the primary plus a constant diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 297994455..ad36bded0 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -174,8 +174,8 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg) Sym->Flags |= SC_REF; } - /* Cannot allocate a variable of zero size */ - if (Size == 0) { + /* Cannot allocate a variable of unknown size */ + if (HasUnknownSize (Sym->Type)) { if (IsTypeArray (Decl->Type)) { Error ("Array '%s' has unknown size", Decl->Ident); } else { @@ -370,8 +370,8 @@ static void ParseAutoDecl (Declaration* Decl) } } - /* Cannot allocate a variable of zero size */ - if (Size == 0) { + /* Cannot allocate an incomplete variable */ + if (HasUnknownSize (Sym->Type)) { if (IsTypeArray (Decl->Type)) { Error ("Array '%s' has unknown size", Decl->Ident); } else { @@ -428,8 +428,8 @@ static void ParseStaticDecl (Declaration* Decl) } - /* Cannot allocate a variable of zero size */ - if (Size == 0) { + /* Cannot allocate an incomplete variable */ + if (HasUnknownSize (Sym->Type)) { if (IsTypeArray (Decl->Type)) { Error ("Array '%s' has unknown size", Decl->Ident); } else { diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index ee0bd1a85..00555ffc3 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -206,7 +206,7 @@ void SwitchStatement (void) void CaseLabel (void) -/* Handle a case sabel */ +/* Handle a case label */ { ExprDesc CaseExpr; /* Case label expression */ long Val; /* Case label value */ diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index a7528a2f8..c72b2c5eb 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -143,10 +143,10 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Do the integer constant <-> absolute address conversion if necessary */ if (IsClassPtr (NewType)) { - Expr->Flags &= ~E_LOC_NONE; + Expr->Flags &= ~E_MASK_LOC; Expr->Flags |= E_LOC_ABS | E_ADDRESS_OF; } else if (IsClassInt (NewType)) { - Expr->Flags &= ~(E_LOC_ABS | E_ADDRESS_OF); + Expr->Flags &= ~(E_MASK_LOC | E_ADDRESS_OF); Expr->Flags |= E_LOC_NONE; }