+2004-02-04 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
+
+ * src/SDCCicode.c (geniCodeParms),
+ * src/SDCCast.c (decorateType, processParms): support for ANSI-style
+ function pointers, fixed function pointer bugs #861242 and #861896
+
2004-01-31 Frieder Ferlemann <Frieder.Ferlemann AT web.de>
* device/include/c8051f000.h,
bool rightmost)
{
RESULT_TYPE resultType;
+ sym_link *functype;
/* if none of them exist */
if (!defParm && !actParm)
checkTypeSanity(defParm->etype, defParm->name);
}
+ if (IS_CODEPTR (func->ftype))
+ functype = func->ftype->next;
+ else
+ functype = func->ftype;
+
/* if the function is being called via a pointer & */
/* it has not been defined a reentrant then we cannot */
/* have parameters */
- if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
+ if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
{
werror (W_NONRENT_ARGS);
return 1;
/* if defined parameters ended but actual parameters */
/* exist and this is not defined as a variable arg */
- if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
+ if (!defParm && actParm && !IFFUNC_HASVARARGS(functype))
{
- /* if (func->type==EX_VALUE && func->opval.val->sym->undefined) */
- /* return 1; *//* Already gave them an undefined function error */
werror (E_TOO_MANY_PARMS);
return 1;
}
}
/* If this is a varargs function... */
- if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
+ if (!defParm && actParm && IFFUNC_HASVARARGS(functype))
{
ast *newType = NULL;
sym_link *ftype;
/* if defined parameters ended but actual has not & */
/* reentrant */
if (!defParm && actParm &&
- (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
+ (options.stackAuto || IFFUNC_ISREENT (functype)))
return 0;
resolveSymbols (actParm);
/* function call */
/*----------------------------*/
case CALL:
+
+ /* undo any explicit pointer derefernce; PCALL will handle it instead */
+ if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
+ {
+ if (tree->left->opval.op == '*' && !tree->left->right)
+ tree->left = tree->left->left;
+ }
+
+ /* require a function or pointer to function */
+ if (!IS_FUNC (LTYPE (tree))
+ && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
+ {
+ werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
+ goto errorTreeReturn;
+ }
+
parmNumber = 1;
if (processParms (tree->left,
- FUNC_ARGS(tree->left->ftype),
+ IS_CODEPTR(LTYPE(tree)) ?
+ FUNC_ARGS(tree->left->ftype->next)
+ : FUNC_ARGS(tree->left->ftype),
tree->right, &parmNumber, TRUE)) {
goto errorTreeReturn;
}
}
/* if they are the same size create an assignment */
+
+ /* This seems very dangerous to me, since there are several */
+ /* optimizations (for example, gcse) that don't notice the */
+ /* cast hidden in this assignement and may simplify an */
+ /* iCode to use the original (uncasted) operand. */
+ /* Unfortunately, other things break when this cast is */
+ /* made explicit. Need to fix this someday. */
+ /* -- EEP, 2004/01/21 */
if (getSize (type) == getSize (optype) &&
!IS_BITFIELD (type) &&
!IS_FLOAT (type) &&
if (argVals==NULL) {
// first argument
- argVals=FUNC_ARGS(func->type);
+ if (IS_CODEPTR(func->type))
+ argVals = FUNC_ARGS (func->type->next);
+ else
+ argVals = FUNC_ARGS (func->type);
}
/* if this is a param node then do the left & right */