?? ccheck.c
字號:
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 + -