⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccheck.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
            if( ( typ1 != typ2 ) ) {
                // Types are not the same
                // if extensions are enabled, then we can do a compatible struct test
                if( CompFlags.extensions_enabled ) {
                    if( CompatibleStructs( typ1->u.tag, typ2->u.tag ) != OK) {
                        if( top_level > 0 ) {
                            if( ret_val != PW )
                                ret_val = PM;
                            else
                                ret_val = NO;
                        } else {
                            ret_val = NO;
                        }
                    }
                } else {
                    ret_val = NO;
                }
            }
        } else if( (TYPE_FIELD == typ1->decl_type) || (TYPE_UFIELD == typ1->decl_type) ) { /* CarlYoung 31-Oct-03 */
            if( typ2->u.f.field_width > typ1->u.f.field_width )
                ret_val = AC;
        }
    } else if( typ1->decl_type == TYPE_UNION && top_level > 0 ) {
        if( InUnion( typ1, typ2, 0 ) != OK ) {
            ret_val = NO;
        } else {
            ret_val = PM;
        }
    } else if( typ2->decl_type == TYPE_UNION && top_level > 0 ) {
        if( InUnion( typ2, typ1, 1 )!= OK ) {
            ret_val = NO;
        } else {
            ret_val = PM;
        }
    } else if( typ1->decl_type == TYPE_ARRAY ) {
        if( !IdenticalType( typ1->object, typ2 ) ) {
            ret_val = NO;
        }
    } else if( typ2->decl_type == TYPE_ARRAY ) {
        if( !IdenticalType( typ2->object, typ1 ) ) {
            ret_val = NO;
        }
    } else if( typ1->decl_type >= TYPE_LAST_ENTRY  ||
            typ2->decl_type >= TYPE_LAST_ENTRY ) {
            ret_val = NO;
    } else if( top_level == 0 ) {
        ret_val = CompTable[ typ1->decl_type ][ typ2->decl_type ];
    } else {
        ret_val = NO;
        switch( typ1->decl_type ) {
        case TYPE_CHAR:
        case TYPE_SHORT:
        case TYPE_INT:
        case TYPE_LONG:
        case TYPE_LONG64:
            if( typ2->decl_type == typ1->decl_type+1 ) {
                ret_val = PS;
            } else if( TypeSize( typ1 ) ==   TypeSize( typ2 ) ) {
                ret_val = PM;
            }
            break;
        case TYPE_UCHAR:
        case TYPE_USHORT:
        case TYPE_UINT:
        case TYPE_ULONG:
        case TYPE_ULONG64:
            if( typ2->decl_type+1 == typ1->decl_type ) {
                ret_val = PS;
            } else if( TypeSize( typ1 ) ==   TypeSize( typ2 ) ) {
                ret_val = PM;
            }
            break;
        default:
            break;
        }
    }
    return( ret_val );
}
#define SUBNOT( a, b, on )  ( ( (a&on)|(b&on) )^(a&on) )
static cmp_type CompatibleType( TYPEPTR typ1, TYPEPTR typ2, int assignment )
{
    cmp_type         ret_val;
    cmp_type         ret_pq;
    type_modifiers   typ1_flags, typ2_flags;
    int              top_level;

    top_level = 0;
    typ1_flags = FLAG_NONE;
    typ2_flags = FLAG_NONE;
    ret_pq = OK;
    typ1 = SkipTypeFluff( typ1 ); // skip typedefs go into enums base
    typ2 = SkipTypeFluff( typ2 );
    if( typ1->decl_type == TYPE_POINTER && typ2->decl_type == TYPE_POINTER ) {
    // top level pointer
        typ1_flags = typ1->u.p.decl_flags;
        typ2_flags = typ2->u.p.decl_flags;
        if( assignment ) {
            type_modifiers subnot;

            subnot = SUBNOT( typ1_flags, typ2_flags, QUAL_FLAGS );
            if( subnot ) {  // allow void * =  unaligned *
                if( subnot & (QUAL_FLAGS & ~FLAG_UNALIGNED) ) {
                    ret_pq = PQ;
                } else if( subnot & FLAG_UNALIGNED) {
                    int align1;

                    align1 = GetTypeAlignment( typ1->object );
                    if( align1 > 1 ) {
                        ret_pq = PQ;
                    }
                }
            }
            if( (typ1_flags & FLAG_MEM_MODEL)!=(typ2_flags & FLAG_MEM_MODEL) ) {
                int size1, size2;

                size1 = TypeSize( typ1 );
                size2 = TypeSize( typ2 );
                if( size1 < size2 ) {
                   ret_pq = PT;
                } else if( size1 > size2 ) {
                    ret_pq = PX;
                }
            }
        }
        typ1 = typ1->object;
        typ2 = typ2->object;
        ++top_level;
    }
    ret_val = DoCompatibleType( typ1, typ2, top_level, VC_CONVERT );
    if( ret_val == OK ) {
        ret_val = ret_pq;
    }
    return( ret_val );
}

void CompatiblePtrType( TYPEPTR typ1, TYPEPTR typ2 )
{
    switch( CompatibleType( typ1, typ2, 0 ) ) {
    case PT:                                        /* 31-aug-89 */
    case PX:
        break;
    case PQ:
        if( !CompFlags.no_check_qualifiers ) { // else fuck em
            CWarn1( WARN_QUALIFIER_MISMATCH, ERR_QUALIFIER_MISMATCH );
        }
        break;
    case PM:                                    /* 16-may-91 */
    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;
    }
}

static void CompareParms( TYPEPTR *master,
                          TREEPTR *passed,
                          int source_fno,
                          int call_line )
{
    TYPEPTR     typ;
    TYPEPTR     typ2;
    int         parm_num;
    TREEPTR     parm;
    char        *filename;

    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 */
        }
    }
    ErrLine = call_line;
    filename = FileIndexToCorrectName( source_fno );
    parm_num = 1;
    while( typ != NULL  &&  *passed != 0 ) {
        SymLoc = filename;
        while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        //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 );
        }
        parm = *passed;
        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 */
            SetDiagType2 ( typ2, typ );
            cmp = CompatibleType( typ, typ2, 1 );
            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 fuck 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:
                if( 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();
        }
        ++master;
        typ = *master;
        ++passed;
        if( typ == NULL ) break;
        if( typ->decl_type == TYPE_DOT_DOT_DOT ) return;
        ++parm_num;
    }
    if( typ != NULL || *passed != 0 ) {     /* should both be NULL now */
#if _CPU == 386
        /* can allow wrong number of parms with -3s option; 06-dec-91 */
        if( ! CompFlags.register_conventions ) {
            SymLoc = filename;
            CWarn1( WARN_PARM_COUNT_MISMATCH, ERR_PARM_COUNT_WARNING );
            SymLoc = NULL;
            return;
        }
#endif
        SymLoc = filename;
        CErr1( ERR_PARM_COUNT_MISMATCH );           /* 18-feb-90 */
    }
    SymLoc = NULL;
}

extern  call_list *CallNodeList;

extern void ChkCallParms( void )
{
    call_list  *nextcall;
    TREEPTR     *actualparmlist;

    actualparmlist = (TREEPTR *)&ValueStack[0];
    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;
            while( typ->decl_type == TYPE_TYPEDEF )  typ = typ->object;
            if( typ->u.parms != NULL ) {
                unsigned    parm_count;
                TREEPTR     parm;

                parm = callnode->right;
                parm_count = 0;
                while( parm != NULL ) {
                    actualparmlist[parm_count] = parm;
                    ++parm_count;
                    parm = parm->left;
                }
                actualparmlist[parm_count] = NULL;
                if( ParmsToBeReversed( sym.attrib, NULL ) ) {
                    int         i, j;
                    TREEPTR     tmp;

                    j = parm_count - 1;
                    for( i = 0; i < j; ++i, --j ) {
                        tmp = actualparmlist[i];
                        actualparmlist[i] = actualparmlist[j];
                        actualparmlist[j] = tmp;
                    }
                }
                SetDiagSymbol( &sym, callsite->op.sym_handle );
                CompareParms( typ->u.parms, actualparmlist,
                                    nextcall->source_fno,
                                    nextcall->srclinenum );
                SetDiagPop();
            }
        }
        next = nextcall->next;
        CMemFree( nextcall  );
        nextcall = next;
    }
}

#define MAXSIZE        (sizeof( long )*8)
static void AssRangeChk( TYPEPTR typ1, TREEPTR opnd2 )
{
    unsigned       long high;
    if( opnd2->op.opr == OPR_PUSHINT ) {
        switch( typ1->decl_type ) {
        case TYPE_FIELD:
        case TYPE_UFIELD:
            high = 0xfffffffful >> (MAXSIZE - (typ1->u.f.field_width));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -