Exemplo n.º 1
0
void CompatiblePtrType( TYPEPTR typ1, TYPEPTR typ2, TOKEN opr )
{
    SetDiagType3( typ1, typ2, opr ); /* Called with source, target. */
    switch( CompatibleType( typ1, typ2, false, false ) ) {
    case PT:
    case PX:
        break;
    case PQ:
        if( !CompFlags.no_check_qualifiers ) { // else f**k em
            CWarn1( WARN_QUALIFIER_MISMATCH, ERR_QUALIFIER_MISMATCH );
        }
        break;
    case PM:
    case NO:
        CWarn1( WARN_POINTER_TYPE_MISMATCH, ERR_POINTER_TYPE_MISMATCH );
        break;
    case PS:
        CWarn1( WARN_SIGN_MISMATCH, ERR_SIGN_MISMATCH );
        break;
    case PW:
        CWarn1( WARN_INCONSISTENT_INDIRECTION_LEVEL, ERR_INCONSISTENT_INDIRECTION_LEVEL );
        break;
    case PC:
        CWarn1( WARN_PCTYPE_MISMATCH, ERR_PCTYPE_MISMATCH );
        break;
    case OK:
    case AC:
        break;
    }
    SetDiagPop();
}
Exemplo n.º 2
0
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 );
}
Exemplo n.º 3
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;
    }
}
Exemplo n.º 4
0
/* Check parameters of function that were called before a prototype was seen */
extern void ChkCallParms( void )
{
    call_list   *nextcall;
    call_list   *next;

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

        next = nextcall->next;
        callnode = nextcall->callnode;
        if( callnode != NULL ) {
            callsite = callnode->left;      // point to OPR_FUNCNAME node
            SymGet( &sym, callsite->op.u2.sym_handle );
            typ = sym.sym_type;
            SKIP_TYPEDEFS( typ );
            if( (sym.flags & SYM_TEMP) == 0 )
                SetDiagSymbol( &sym, callsite->op.u2.sym_handle );
            SetErrLoc( &nextcall->src_loc );
            if( typ->u.fn.parms != NULL ) {
                CompareParms( typ->u.fn.parms, callnode->right, ParmsToBeReversed( sym.mods, NULL ) );
            } else {
                // Unprototyped function called. Note that for indirect calls, there
                // is no symbol associated with the function and diagnostic information
                // is hence limited.
                if( sym.flags & SYM_TEMP ) {
                    CWarn1( WARN_NONPROTO_FUNC_CALLED_INDIRECT, ERR_NONPROTO_FUNC_CALLED_INDIRECT );
                } else {
                    CWarn2p( WARN_NONPROTO_FUNC_CALLED, ERR_NONPROTO_FUNC_CALLED, SymName( &sym, callsite->op.u2.sym_handle ) );
                }
            }
            InitErrLoc();
            if( (sym.flags & SYM_TEMP) == 0 ) {
                SetDiagPop();
            }
        }
        CMemFree( nextcall );
    }
}
Exemplo n.º 5
0
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 */
}
Exemplo n.º 6
0
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 */
    }
}