Example #1
0
/* Check parameters of function that were called before a prototype was seen */
extern void ChkCallParms( void )
{
    call_list   *nextcall;

    nextcall = CallNodeList;
    while( nextcall != NULL ) {
        call_list  *next;
        TREEPTR     callnode;
        TREEPTR     callsite;
        SYM_ENTRY   sym;
        TYPEPTR     typ;

        callnode = nextcall->callnode;
        if( callnode != NULL ) {
            callsite = callnode->left;      // point to OPR_FUNCNAME node
            SymGet( &sym, callsite->op.sym_handle );
            typ = sym.sym_type;
            SKIP_TYPEDEFS( typ );
            if( !(sym.flags & SYM_TEMP) )
                SetDiagSymbol( &sym, callsite->op.sym_handle );
            if( typ->u.fn.parms != NULL ) {
                TREEPTR     parms;
                bool        reverse;

                parms = callnode->right;
                reverse = ( ParmsToBeReversed( sym.attrib, NULL ) && ( parms != NULL ) );
                if( reverse ) {
                    parms = reverse_parms_tree( parms );
                }
                CompareParms( typ->u.fn.parms, parms, &nextcall->src_loc );
                if( reverse ) {
                    reverse_parms_tree( parms );
                }
            } else {
                // Unprototyped function called. Note that for indirect calls, there
                // is no symbol associated with the function and diagnostic information
                // is hence limited.
                SetErrLoc( &nextcall->src_loc );
                if( sym.flags & SYM_TEMP ) {
                    CWarn( WARN_NONPROTO_FUNC_CALLED_INDIRECT,
                            ERR_NONPROTO_FUNC_CALLED_INDIRECT );
                } else {
                    CWarn( WARN_NONPROTO_FUNC_CALLED,
                            ERR_NONPROTO_FUNC_CALLED, SymName( &sym, callsite->op.sym_handle ) );
                }
            }
            if( !(sym.flags & SYM_TEMP) ) {
                SetDiagPop();
        }
        }
        next = nextcall->next;
        CMemFree( nextcall );
        nextcall = next;
    }
}
Example #2
0
static void CompareParms( TYPEPTR *master, TREEPTR parms, bool reverse )
{
    TYPEPTR     typ1;
    int         parmno;
    TREEPTR     parm;

    if( reverse ) {
        parms = reverse_parms_tree( parms );
    }
    typ1 = *master++;
    if( typ1 != NULL ) {
        if( typ1->decl_type == TYPE_VOID ) { /* type func(void);  */
            typ1 = NULL;                     /* indicate no parms */
        }
    }
    for( parmno = 1, parm = parms; ( typ1 != NULL ) && ( parm != NULL ); parm = parm->left, ++parmno ) {
        SKIP_TYPEDEFS( typ1 );
        // TODO is crap needed or has it been done
        if( typ1->decl_type == TYPE_FUNCTION ) {
            typ1 = PtrNode( typ1, FLAG_NONE, SEG_CODE );
        } else if( typ1->decl_type == TYPE_ARRAY ) {
            typ1 = PtrNode( typ1->object, FLAG_WAS_ARRAY, SEG_DATA );
        }
        /* check compatibility of parms */
        ParmAsgnCheck( typ1, parm, parmno, false );
        typ1 = *master++;
        if( typ1 != NULL && typ1->decl_type == TYPE_DOT_DOT_DOT ) {
            typ1 = NULL;
            parm = NULL;
            break;
        }
    }
    if( typ1 != NULL || parm != NULL ) {     /* should both be NULL now */
#if _CPU == 386
        /* can allow wrong number of parms with -3s option */
        if( !CompFlags.register_conventions ) {
            CWarn1( WARN_PARM_COUNT_MISMATCH, ERR_PARM_COUNT_WARNING );
        } else {
            CErr1( ERR_PARM_COUNT_MISMATCH );
        }
#else
        CErr1( ERR_PARM_COUNT_MISMATCH );
#endif
    }
    if( reverse ) {
        reverse_parms_tree( parms );
    }
}