From 9ce6d44e135c70f91434bbd2850c80359f62d535 Mon Sep 17 00:00:00 2001 From: epetrich Date: Fri, 6 Feb 2004 06:27:15 +0000 Subject: [PATCH] * src/SDCCast.c (decorateType), * src/SDCCicode.c (geniCodeParms, geniCodeCall): fixed bugs in my ANSI function pointer implementation * support/regression/tests/funptrs.c: added tests to verify both forms of function pointers work correctly. Added tests to verify parameters are passed in the correct order. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3171 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 9 +++++ src/SDCCast.c | 41 ++++++++++---------- src/SDCCicode.c | 28 +++++++------- support/regression/tests/funptrs.c | 60 ++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4f453e79..30535df4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2004-02-06 Erik Petrich + + * src/SDCCast.c (decorateType), + * src/SDCCicode.c (geniCodeParms, geniCodeCall): fixed bugs in my ANSI + function pointer implementation + * support/regression/tests/funptrs.c: added tests to verify both forms + of function pointers work correctly. Added tests to verify parameters + are passed in the correct order. + 2004-02-06 Vangelis Rokas * device.c (regCompare): registers are sorted by ascending diff --git a/src/SDCCast.c b/src/SDCCast.c index 8bf776ba..29ac0a73 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -4046,29 +4046,30 @@ decorateType (ast * tree, RESULT_TYPE resultType) werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED); goto errorTreeReturn; } - - parmNumber = 1; - - if (processParms (tree->left, - IS_CODEPTR(LTYPE(tree)) ? - FUNC_ARGS(tree->left->ftype->next) - : FUNC_ARGS(tree->left->ftype), - tree->right, &parmNumber, TRUE)) { - goto errorTreeReturn; - } - if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && - !IFFUNC_ISBUILTIN(LTYPE(tree))) - { - reverseParms (tree->right); - } + { + sym_link *functype; + parmNumber = 1; - if (IS_CODEPTR(LTYPE(tree))) { - TTYPE(tree) = LTYPE(tree)->next->next; - } else { - TTYPE(tree) = LTYPE(tree)->next; + if (IS_CODEPTR(LTYPE(tree))) + functype = LTYPE (tree)->next; + else + functype = LTYPE (tree); + + if (processParms (tree->left, FUNC_ARGS(functype), + tree->right, &parmNumber, TRUE)) { + goto errorTreeReturn; + } + + if ((options.stackAuto || IFFUNC_ISREENT (functype)) && + !IFFUNC_ISBUILTIN(functype)) + { + reverseParms (tree->right); + } + + TTYPE (tree) = functype->next; + TETYPE (tree) = getSpec (TTYPE (tree)); } - TETYPE (tree) = getSpec (TTYPE (tree)); return tree; /*------------------------------------------------------------------*/ diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 100c4fec..e0191b11 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -3038,7 +3038,7 @@ geniCodeSEParms (ast * parms,int lvl) /*-----------------------------------------------------------------*/ value * geniCodeParms (ast * parms, value *argVals, int *stack, - sym_link * fetype, symbol * func,int lvl) + sym_link * ftype, int lvl) { iCode *ic; operand *pval; @@ -3048,17 +3048,14 @@ geniCodeParms (ast * parms, value *argVals, int *stack, if (argVals==NULL) { // first argument - if (IS_CODEPTR(func->type)) - argVals = FUNC_ARGS (func->type->next); - else - argVals = FUNC_ARGS (func->type); + argVals = FUNC_ARGS (ftype); } /* if this is a param node then do the left & right */ if (parms->type == EX_OP && parms->opval.op == PARAM) { - argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl); - argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl); + argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl); + argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl); return argVals; } @@ -3082,18 +3079,18 @@ geniCodeParms (ast * parms, value *argVals, int *stack, } /* if register parm then make it a send */ - if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) || - IFFUNC_ISBUILTIN(func->type)) + if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) || + IFFUNC_ISBUILTIN(ftype)) { ic = newiCode (SEND, pval, NULL); ic->argreg = SPEC_ARGREG(parms->etype); - ic->builtinSEND = FUNC_ISBUILTIN(func->type); + ic->builtinSEND = FUNC_ISBUILTIN(ftype); ADDTOCHAIN (ic); } else { /* now decide whether to push or assign */ - if (!(options.stackAuto || IFFUNC_ISREENT (func->type))) + if (!(options.stackAuto || IFFUNC_ISREENT (ftype))) { /* assign */ @@ -3127,6 +3124,7 @@ geniCodeCall (operand * left, ast * parms,int lvl) iCode *ic; operand *result; sym_link *type, *etype; + sym_link *ftype; int stack = 0; if (!IS_FUNC(OP_SYMBOL(left)->type) && @@ -3140,8 +3138,12 @@ geniCodeCall (operand * left, ast * parms,int lvl) of overlaying function parameters */ geniCodeSEParms (parms,lvl); + ftype = operandType (left); + if (IS_CODEPTR (ftype)) + ftype = ftype->next; + /* first the parameters */ - geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl); + geniCodeParms (parms, NULL, &stack, ftype, lvl); /* now call : if symbol then pcall */ if (IS_OP_POINTER (left) || IS_ITEMP(left)) { @@ -3150,7 +3152,7 @@ geniCodeCall (operand * left, ast * parms,int lvl) ic = newiCode (CALL, left, NULL); } - type = copyLinkChain (operandType (left)->next); + type = copyLinkChain (ftype->next); etype = getSpec (type); SPEC_EXTR (etype) = 0; IC_RESULT (ic) = result = newiTempOperand (type, 1); diff --git a/support/regression/tests/funptrs.c b/support/regression/tests/funptrs.c index 1e2e7e1e..ad5248b8 100644 --- a/support/regression/tests/funptrs.c +++ b/support/regression/tests/funptrs.c @@ -9,8 +9,10 @@ */ typedef void (*NOARGFUNPTR)(void); typedef void (*ONEARGFUNPTR)({type}) REENTRANT; +typedef long int (*FOURARGFUNPTR)(char, char, long int, long int) REENTRANT; int count; +FOURARGFUNPTR fafp; void incCount(void) @@ -24,6 +26,19 @@ incBy({type} a) REENTRANT count += a; } +long int f6(char a, char b, long int c, long int d) REENTRANT +{ + switch (a) + { + case 0: return a; + case 1: return b; + case 2: return c; + case 3: return d; + } + return 0; +} + + void callViaPtr(NOARGFUNPTR fptr) { @@ -42,12 +57,57 @@ callViaPtr3(void (*fptr)(void)) (*fptr)(); } +void +callViaPtrAnsi(NOARGFUNPTR fptr) +{ + fptr(); +} + +void +callViaPtr2Ansi(ONEARGFUNPTR fptr, {type} arg) +{ + fptr(arg); +} + +void +callViaPtr3Ansi(void (*fptr)(void)) +{ + fptr(); +} + + + void testFunPtr(void) { + fafp = f6; + ASSERT(count == 0); callViaPtr(incCount); ASSERT(count == 1); callViaPtr2(incBy, 7); ASSERT(count == 8); + + ASSERT((*fafp)(0, 0x55, 0x12345678, 0x9abcdef0) == 0); + ASSERT((*fafp)(1, 0x55, 0x12345678, 0x9abcdef0) == 0x55); + ASSERT((*fafp)(2, 0x55, 0x12345678, 0x9abcdef0) == 0x12345678); + ASSERT((*fafp)(3, 0x55, 0x12345678, 0x9abcdef0) == 0x9abcdef0); +} + +void +testFunPtrAnsi(void) +{ + fafp = f6; + + count = 0; + callViaPtrAnsi(incCount); + ASSERT(count == 1); + callViaPtr2Ansi(incBy, 7); + ASSERT(count == 8); + + ASSERT(fafp(0, 0x55, 0x12345678, 0x9abcdef0) == 0); + ASSERT(fafp(1, 0x55, 0x12345678, 0x9abcdef0) == 0x55); + ASSERT(fafp(2, 0x55, 0x12345678, 0x9abcdef0) == 0x12345678); + ASSERT(fafp(3, 0x55, 0x12345678, 0x9abcdef0) == 0x9abcdef0); } + -- 2.47.2