From 30fd8592ae6332b9b4eaa64abd87c11d81f2d586 Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 1 Aug 2020 22:06:14 +0800 Subject: [PATCH] Avoid internal errors when using function-type objects in expressions. --- src/cc65/datatype.c | 19 ++++++++++++++++++- src/cc65/datatype.h | 3 +++ src/cc65/expr.c | 6 +++--- src/cc65/function.c | 2 +- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 1e2859ba7..18dd0a6b1 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -732,7 +732,8 @@ unsigned TypeOf (const Type* T) return CF_FLOAT; case T_FUNC: - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC)? 0 : CF_FIXARGC; + /* Treat this as a function pointer */ + return CF_INT | CF_UNSIGNED; case T_STRUCT: case T_UNION: @@ -751,6 +752,22 @@ unsigned TypeOf (const Type* T) +unsigned FuncTypeOf (const Type* T) +/* Get the code generator flag for calling the function */ +{ + switch (GetUnderlyingTypeCode (T)) { + + case T_FUNC: + return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + + default: + Error ("Illegal function type %04lX", T->C); + return 0; + } +} + + + Type* Indirect (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 1997b5c89..33c66d65d 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -323,6 +323,9 @@ unsigned CheckedPSizeOf (const Type* T); unsigned TypeOf (const Type* T); /* Get the code generator base type of the object */ +unsigned FuncTypeOf (const Type* T); +/* Get the code generator flag for calling the function */ + Type* Indirect (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. diff --git a/src/cc65/expr.c b/src/cc65/expr.c index fd8a48002..1d123ce9b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -585,7 +585,7 @@ static void FunctionCall (ExprDesc* Expr) } /* Call the function */ - g_callind (TypeOf (Expr->Type+1), ParamSize, PtrOffs); + g_callind (FuncTypeOf (Expr->Type+1), ParamSize, PtrOffs); } else { @@ -646,9 +646,9 @@ static void FunctionCall (ExprDesc* Expr) SB_Done (&S); - g_call (TypeOf (Expr->Type), Func->WrappedCall->Name, ParamSize); + g_call (FuncTypeOf (Expr->Type), Func->WrappedCall->Name, ParamSize); } else { - g_call (TypeOf (Expr->Type), (const char*) Expr->Name, ParamSize); + g_call (FuncTypeOf (Expr->Type), (const char*) Expr->Name, ParamSize); } } diff --git a/src/cc65/function.c b/src/cc65/function.c index d6e11fea3..e6a974f98 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -487,7 +487,7 @@ void NewFunc (SymEntry* Func) } /* Generate function entry code if needed */ - g_enter (TypeOf (Func->Type), F_GetParamSize (CurrentFunc)); + g_enter (FuncTypeOf (Func->Type), F_GetParamSize (CurrentFunc)); /* If stack checking code is requested, emit a call to the helper routine */ if (IS_Get (&CheckStack)) {