static typecheck_err ChkCompatibleFunctionParms( TYPEPTR typ1, TYPEPTR typ2, bool topLevelCheck ) { TYPEPTR *plist1; TYPEPTR *plist2; TYPEPTR p1; TYPEPTR p2; int parmno; typecheck_err rc; rc = TCE_OK; /* indicate functions are compatible */ plist1 = typ1->u.fn.parms; plist2 = typ2->u.fn.parms; if( plist1 != plist2 ) { if( plist1 == NULL ) { plist1 = plist2; plist2 = NULL; } if( plist2 == NULL ) { for( parmno = 1; (p1 = *plist1++) != NULL; ++parmno ) { if( p1->decl_type == TYPE_DOT_DOT_DOT ) { break; } if( !ChkParmPromotion( p1 ) ) { if( topLevelCheck ) { CErr2( ERR_PARM_TYPE_MISMATCH, parmno ); } rc = TCE_TYPE_MISMATCH; } } } else { p1 = *plist1++; p2 = *plist2++; for( parmno = 1; p1 != NULL && p2 != NULL; ++parmno ) { if( p1->decl_type == TYPE_DOT_DOT_DOT || p2->decl_type == TYPE_DOT_DOT_DOT ) { break; } if( !IdenticalType( p1, p2 ) ) { if( topLevelCheck ) { SetDiagType2( p1, p2 ); CErr2( ERR_PARM_TYPE_MISMATCH, parmno ); SetDiagPop(); } rc = TCE_TYPE_MISMATCH; } p1 = *plist1++; p2 = *plist2++; } if( p1 != NULL && p1->decl_type == TYPE_DOT_DOT_DOT || p2 != NULL && p2->decl_type == TYPE_DOT_DOT_DOT ) { p1 = NULL; p2 = NULL; } if( p1 != NULL || p2 != NULL ) { if( topLevelCheck ) { CErr1( ERR_PARM_COUNT_MISMATCH ); } rc = TCE_PARM_COUNT_MISMATCH; } } } return( rc ); }
static int ChkParmPromotion( TYPEPTR *plist, int topLevelCheck ) /* 25-nov-94 */ { TYPEPTR typ; int parm_count; parm_count = 1; for( ;; ) { typ = *plist++; if( typ == NULL ) break; SKIP_TYPEDEFS( typ ); switch( typ->decl_type ) { case TYPE_CHAR: case TYPE_UCHAR: case TYPE_SHORT: if( CompFlags.strict_ANSI ) { if( topLevelCheck ) { CErr2( ERR_PARM_TYPE_MISMATCH, parm_count ); } return( TC_TYPE_MISMATCH ); } break; case TYPE_USHORT: #if TARGET_SHORT != TARGET_INT if( CompFlags.strict_ANSI ) { if( topLevelCheck ) { CErr2( ERR_PARM_TYPE_MISMATCH, parm_count ); } return( TC_TYPE_MISMATCH ); } #endif break; case TYPE_FLOAT: if( topLevelCheck ) { CErr2( ERR_PARM_TYPE_MISMATCH, parm_count ); } return( TC_TYPE_MISMATCH ); default: break; } } return( TC_OK ); }
int ChkCompatibleFunction( TYPEPTR typ1, TYPEPTR typ2, int topLevelCheck ) { TYPEPTR *plist1; TYPEPTR *plist2; int parm_count; plist1 = typ1->u.fn.parms; plist2 = typ2->u.fn.parms; if( plist1 != plist2 ) { if( plist1 == NULL ) { return( ChkParmPromotion( plist2, topLevelCheck ) ); } else if( plist2 == NULL ) { return( ChkParmPromotion( plist1, topLevelCheck ) ); } parm_count = 1; for( ;; ) { if( *plist1 == NULL && *plist2 == NULL ) break; if( *plist1 == NULL || *plist2 == NULL ) { if( topLevelCheck ) { CErr1( ERR_PARM_COUNT_MISMATCH ); } return( TC_PARM_COUNT_MISMATCH ); } if( ! IdenticalType( *plist1, *plist2 ) ) { if( topLevelCheck ) { SetDiagType2( *plist1, *plist2 ); CErr2( ERR_PARM_TYPE_MISMATCH, parm_count ); SetDiagPop(); } return( TC_PARM_TYPE_MISMATCH + parm_count ); } ++plist1; ++plist2; ++parm_count; } } return( TC_OK ); /* indicate functions are compatible */ }
static void ioSuppError( // SIGNAL I/O ERROR AND ABORT int error_code ) // - error code { CErr2( error_code, errno ); CSuicide(); }
static void CompareParms( TYPEPTR *master, TREEPTR parm, source_loc *src_loc ) { TYPEPTR typ; TYPEPTR typ2; int parm_num; cmp_type cmp; typ = *master++; if( typ != NULL ) { /* 27-feb-90 */ if( typ->decl_type == TYPE_VOID ) { /* type func(void); */ typ = NULL; /* indicate no parms */ } } parm_num = 1; while( ( typ != NULL ) && ( parm != NULL ) ) { SKIP_TYPEDEFS( typ ); // TODO is crap needed or has it been done if( typ->decl_type == TYPE_FUNCTION ) { typ = PtrNode( typ, FLAG_NONE, SEG_CODE ); } else if( typ->decl_type == TYPE_ARRAY ) { typ = PtrNode( typ->object, FLAG_WAS_ARRAY, SEG_DATA ); } typ2 = parm->expr_type; // typ2 will be NULL if parm is OPR_ERROR in which case an error // has already been generated if( typ2 != NULL ) { /* check compatibility of parms */ SetErrLoc( src_loc ); SetDiagType2 ( typ2, typ ); cmp = CompatibleType( typ, typ2, TRUE, IsNullConst( parm ) ); switch( cmp ) { case NO: case PT: case PX: case AC: CErr2( ERR_PARM_TYPE_MISMATCH, parm_num ); break; case PQ: if( !CompFlags.no_check_qualifiers ) { // else f**k em CWarn2( WARN_QUALIFIER_MISMATCH, ERR_PARM_QUALIFIER_MISMATCH, parm_num ); } break; case PM: /* 16-may-91 */ CWarn2( WARN_POINTER_TYPE_MISMATCH, ERR_PARM_POINTER_TYPE_MISMATCH, parm_num ); break; case PS: CWarn2( WARN_SIGN_MISMATCH, ERR_PARM_SIGN_MISMATCH, parm_num ); break; case PW: CWarn2( WARN_PARM_INCONSISTENT_INDIRECTION_LEVEL, ERR_PARM_INCONSISTENT_INDIRECTION_LEVEL, parm_num ); break; case PC: /* Allow only "void *p = int 0"; */ if( IsPointer( typ ) && parm->right->op.opr == OPR_PUSHINT ) { if( TypeSize(typ) != TypeSize(typ2) ) { CErr2( ERR_PARM_TYPE_MISMATCH, parm_num ); } else if( parm->right->op.ulong_value != 0 ) { CWarn1( WARN_NONPORTABLE_PTR_CONV, ERR_NONPORTABLE_PTR_CONV ); } } else { if( TypeSize(typ->object) == TypeSize(typ2->object) ) { CWarn2( WARN_POINTER_TYPE_MISMATCH, ERR_PARM_POINTER_TYPE_MISMATCH, parm_num ); } else { CErr2( ERR_PARM_TYPE_MISMATCH, parm_num ); } } break; case OK: break; } SetDiagPop(); InitErrLoc(); } typ = *master++; if( typ != NULL && typ->decl_type == TYPE_DOT_DOT_DOT ) return; parm = parm->left; ++parm_num; } if( typ != NULL || parm != NULL ) { /* should both be NULL now */ SetErrLoc( src_loc ); #if _CPU == 386 /* can allow wrong number of parms with -3s option; 06-dec-91 */ if( !CompFlags.register_conventions ) { CWarn1( WARN_PARM_COUNT_MISMATCH, ERR_PARM_COUNT_WARNING ); return; } #endif CErr1( ERR_PARM_COUNT_MISMATCH ); /* 18-feb-90 */ } }