1
0
mirror of https://github.com/cc65/cc65.git synced 2025-08-08 06:25:17 +00:00

Merge pull request #1783 from acqn/MiscFixes

[cc65] Misc fixes and improvements
This commit is contained in:
Bob Andrews
2022-07-19 17:37:19 +02:00
committed by GitHub
12 changed files with 74 additions and 54 deletions

View File

@@ -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 */ /* Code */
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -218,14 +218,16 @@ static void Parse (void)
** void types in ISO modes. ** void types in ISO modes.
*/ */
if (Size == 0) { if (Size == 0) {
if (!IsTypeVoid (Decl.Type)) { if (!IsEmptiableObjectType (Decl.Type)) {
if (!IsTypeArray (Decl.Type)) { if (!IsTypeArray (Decl.Type)) {
/* Size is unknown and not an array */ /* 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) { } else if (IS_Get (&Standard) != STD_CC65) {
/* We cannot declare variables of type void */ /* 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 */ /* We cannot declare variables of type void */
Error ("Illegal type for variable '%s'", Decl.Ident); Error ("Illegal type for variable '%s'", Decl.Ident);
Entry->Flags &= ~(SC_STORAGE | SC_DEF); 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? */ /* Size is unknown. Is it an array? */
if (!IsTypeArray (Decl.Type)) { if (!IsTypeArray (Decl.Type)) {
Error ("Variable '%s' has unknown size", Decl.Ident); Error ("Variable '%s' has unknown size", Decl.Ident);

View File

@@ -805,7 +805,11 @@ unsigned CheckedSizeOf (const Type* T)
{ {
unsigned Size = SizeOf (T); unsigned Size = SizeOf (T);
if (Size == 0) { 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 */ Size = SIZEOF_CHAR; /* Don't return zero */
} }
return Size; return Size;
@@ -821,7 +825,11 @@ unsigned CheckedPSizeOf (const Type* T)
{ {
unsigned Size = PSizeOf (T); unsigned Size = PSizeOf (T);
if (Size == 0) { 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 */ Size = SIZEOF_CHAR; /* Don't return zero */
} }
return Size; 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) const Type* IntPromotion (const Type* T)
/* Apply the integer promotions to T and return the result. The returned type /* 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. ** string may be T if there is no need to change it.

View File

@@ -368,6 +368,12 @@ const Type* PtrConversion (const Type* T);
** return 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); const Type* IntPromotion (const Type* T);
/* Apply the integer promotions to T and return the result. The returned type /* 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. ** string may be T if there is no need to change it.

View File

@@ -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 */ /* Descriptors for the operations */
static GenDesc GenPASGN = { TOK_PLUS_ASSIGN, GEN_NOPUSH, g_add }; static GenDesc GenPASGN = { TOK_PLUS_ASSIGN, GEN_NOPUSH, g_add };
static GenDesc GenSASGN = { TOK_MINUS_ASSIGN, GEN_NOPUSH, g_sub }; 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 */ /* Find a token in a generator table */
{ {
while (Table->Tok != TOK_INVALID) { while (Table->Tok != TOK_INVALID) {
if (Table->Tok == Tok) { if ((token_t)Table->Tok == Tok) {
return Table; return Table;
} }
++Table; ++Table;
@@ -772,9 +765,10 @@ static unsigned FunctionArgList (FuncDesc* Func, int IsFastcall, ExprDesc* ED)
} else { } else {
/* No prototype available. Convert array to "pointer to first /* 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 */ /* output its label */
E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF;
E->Name = Entry->V.L.Label; E->Name = Entry->V.L.Label;
E->Type = NewPointerTo (type_void); E->Type = type_void_p;
NextToken (); NextToken ();
} else { } else {
Error ("Computed gotos are a C extension, not supported with this --standard"); 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 */ /* The & operator yields an rvalue address */
ED_AddrExpr (Expr); ED_AddrExpr (Expr);
} }
Expr->Type = NewPointerTo (Expr->Type); Expr->Type = AddressOf (Expr->Type);
break; break;
case TOK_SIZEOF: case TOK_SIZEOF:
@@ -2271,9 +2265,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
Tok = CurTok.Tok; Tok = CurTok.Tok;
NextToken (); 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)) { if (IsTypeFunc (Expr->Type)) {
Expr->Type = NewPointerTo (Expr->Type); Expr->Type = AddressOf (Expr->Type);
} }
/* Get the lhs on stack */ /* Get the lhs on stack */
@@ -2293,9 +2287,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
/* Get the right hand side */ /* Get the right hand side */
MarkedExprWithCheck (hienext, &Expr2); 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)) { if (IsTypeFunc (Expr2.Type)) {
Expr2.Type = NewPointerTo (Expr2.Type); Expr2.Type = AddressOf (Expr2.Type);
} }
/* Check for a numeric constant expression */ /* Check for a numeric constant expression */
@@ -3069,7 +3063,7 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef)
Error ("Invalid operands for binary operator '+'"); Error ("Invalid operands for binary operator '+'");
} else { } else {
/* Array and function types must be converted to pointer types */ /* 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 */ /* Result type is either a pointer or an integer */
Expr->Type = PtrConversion (Expr->Type); Expr->Type = StdConversion (Expr->Type);
/* Condition code not set */ /* Condition code not set */
ED_MarkAsUntested (Expr); ED_MarkAsUntested (Expr);

View File

@@ -26,13 +26,20 @@
#define SQP_KEEP_NONE 0x00 #define SQP_KEEP_NONE 0x00
#define SQP_KEEP_TEST 0x01U #define SQP_KEEP_TEST 0x01U
#define SQP_KEEP_EAX 0x02U #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 */ /* Generator attributes */
#define GEN_NOPUSH 0x01 /* Don't push lhs */ #define GEN_NOPUSH 0x01 /* Don't push lhs */
#define GEN_COMM 0x02 /* Operator is commutative */ #define GEN_COMM 0x02 /* Operator is commutative */
#define GEN_NOFUNC 0x04 /* Not allowed for function pointers */ #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;
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -93,8 +93,7 @@ int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr)
int ED_IsIndExpr (const ExprDesc* Expr) int ED_IsIndExpr (const ExprDesc* Expr)
/* Check if the expression is a reference to its value */ /* Check if the expression is a reference to its value */
{ {
return (Expr->Flags & E_ADDRESS_OF) == 0 && return (Expr->Flags & E_ADDRESS_OF) == 0 && !ED_IsLocNone (Expr);
!ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr);
} }
#endif #endif
@@ -282,7 +281,7 @@ ExprDesc* ED_AddrExpr (ExprDesc* Expr)
case E_LOC_EXPR: case E_LOC_EXPR:
Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE); 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; break;
default: default:

View File

@@ -493,8 +493,7 @@ INLINE int ED_IsAddrExpr (const ExprDesc* Expr)
INLINE int ED_IsIndExpr (const ExprDesc* Expr) INLINE int ED_IsIndExpr (const ExprDesc* Expr)
/* Check if the expression is a reference to its value */ /* Check if the expression is a reference to its value */
{ {
return (Expr->Flags & E_ADDRESS_OF) == 0 && return (Expr->Flags & E_ADDRESS_OF) == 0 && !ED_IsLocNone (Expr);
!ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr);
} }
#else #else
int ED_IsIndExpr (const ExprDesc* Expr); int ED_IsIndExpr (const ExprDesc* Expr);

View File

@@ -92,6 +92,7 @@ static void LoadAddress (unsigned Flags, ExprDesc* Expr)
g_leasp (Expr->IVal); g_leasp (Expr->IVal);
break; break;
case E_LOC_PRIMARY:
case E_LOC_EXPR: case E_LOC_EXPR:
if (Expr->IVal != 0) { if (Expr->IVal != 0) {
/* We have an expression in the primary plus a constant /* We have an expression in the primary plus a constant

View File

@@ -174,8 +174,8 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg)
Sym->Flags |= SC_REF; Sym->Flags |= SC_REF;
} }
/* Cannot allocate a variable of zero size */ /* Cannot allocate a variable of unknown size */
if (Size == 0) { if (HasUnknownSize (Sym->Type)) {
if (IsTypeArray (Decl->Type)) { if (IsTypeArray (Decl->Type)) {
Error ("Array '%s' has unknown size", Decl->Ident); Error ("Array '%s' has unknown size", Decl->Ident);
} else { } else {
@@ -370,8 +370,8 @@ static void ParseAutoDecl (Declaration* Decl)
} }
} }
/* Cannot allocate a variable of zero size */ /* Cannot allocate an incomplete variable */
if (Size == 0) { if (HasUnknownSize (Sym->Type)) {
if (IsTypeArray (Decl->Type)) { if (IsTypeArray (Decl->Type)) {
Error ("Array '%s' has unknown size", Decl->Ident); Error ("Array '%s' has unknown size", Decl->Ident);
} else { } else {
@@ -428,8 +428,8 @@ static void ParseStaticDecl (Declaration* Decl)
} }
/* Cannot allocate a variable of zero size */ /* Cannot allocate an incomplete variable */
if (Size == 0) { if (HasUnknownSize (Sym->Type)) {
if (IsTypeArray (Decl->Type)) { if (IsTypeArray (Decl->Type)) {
Error ("Array '%s' has unknown size", Decl->Ident); Error ("Array '%s' has unknown size", Decl->Ident);
} else { } else {

View File

@@ -206,7 +206,7 @@ void SwitchStatement (void)
void CaseLabel (void) void CaseLabel (void)
/* Handle a case sabel */ /* Handle a case label */
{ {
ExprDesc CaseExpr; /* Case label expression */ ExprDesc CaseExpr; /* Case label expression */
long Val; /* Case label value */ long Val; /* Case label value */

View File

@@ -143,10 +143,10 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType)
/* Do the integer constant <-> absolute address conversion if necessary */ /* Do the integer constant <-> absolute address conversion if necessary */
if (IsClassPtr (NewType)) { if (IsClassPtr (NewType)) {
Expr->Flags &= ~E_LOC_NONE; Expr->Flags &= ~E_MASK_LOC;
Expr->Flags |= E_LOC_ABS | E_ADDRESS_OF; Expr->Flags |= E_LOC_ABS | E_ADDRESS_OF;
} else if (IsClassInt (NewType)) { } 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; Expr->Flags |= E_LOC_NONE;
} }