/* 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; } }
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 ); } }