| @@ -3312,12 +3312,25 @@ static void type_to_str(char *buf, int buf_size, · 3311 unmodified lines |
| 3312 | 3312 | no_var: ; |
| 3313 | 3313 | } |
| 3314 | 3314 | |
| 3315 | | −static void cast_error(CType *st, CType *dt) |
| 3315 | +static void type_incompatibility_error(CType* st, CType* dt, const char* fmt) |
| 3316 | +{ |
| 3317 | + char buf1[256], buf2[256]; |
| 3318 | + type_to_str(buf1, sizeof(buf1), st, NULL); |
| 3319 | + type_to_str(buf2, sizeof(buf2), dt, NULL); |
| 3320 | + tcc_error(fmt, buf1, buf2); |
| 3321 | +} |
| 3322 | + |
| 3323 | +static void type_incompatibility_warning(CType* st, CType* dt, const char* fmt) |
| 3316 | 3324 | { |
| 3317 | 3325 | char buf1[256], buf2[256]; |
| 3318 | 3326 | type_to_str(buf1, sizeof(buf1), st, NULL); |
| 3319 | 3327 | type_to_str(buf2, sizeof(buf2), dt, NULL); |
| 3320 | | − tcc_error("cannot convert '%s' to '%s'", buf1, buf2); |
| 3328 | + tcc_warning(fmt, buf1, buf2); |
| 3329 | +} |
| 3330 | + |
| 3331 | +static void cast_error(CType *st, CType *dt) |
| 3332 | +{ |
| 3333 | + type_incompatibility_error(st, dt, "cannot convert '%s' to '%s'"); |
| 3321 | 3334 | } |
| 3322 | 3335 | |
| 3323 | 3336 | /* verify type compatibility to store vtop in 'dt' type */ |
| @@ -5523,8 +5536,11 @@ special_math_val: · 2199 unmodified lines |
| 5523 | 5536 | test_lvalue(); |
| 5524 | 5537 | gaddrof(); |
| 5525 | 5538 | /* expect pointer on structure */ |
| 5526 | | − if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) |
| 5527 | | − expect("struct or union"); |
| 5539 | + if ( (vtop->type.t & VT_BTYPE) != VT_STRUCT ) { |
| 5540 | + char got[256]; |
| 5541 | + type_to_str(got, sizeof got, &vtop->type, NULL); |
| 5542 | + tcc_error("expected struct or union but not '%s'", got); |
| 5543 | + } |
| 5528 | 5544 | if (tok == TOK_CDOUBLE) |
| 5529 | 5545 | expect("field name"); |
| 5530 | 5546 | next(); |
| @@ -6001,7 +6017,13 @@ static void expr_cond(void) · 470 unmodified lines |
| 6001 | 6017 | /* cast operands to correct type according to ISOC rules */ |
| 6002 | 6018 | if (bt1 == VT_VOID || bt2 == VT_VOID) { |
| 6003 | 6019 | type.t = VT_VOID; /* NOTE: as an extension, we accept void on only one side */ |
| 6004 | | − } else if (is_float(bt1) || is_float(bt2)) { |
| 6020 | + } else if ( bt1 == VT_BOOL && bt2 == VT_BOOL ) { |
| 6021 | + type = type1; |
| 6022 | + } else if ( is_float(bt1) && is_integer_btype(bt2) ) { |
| 6023 | + type = type1; |
| 6024 | + } else if ( is_integer_btype(bt1) && is_float(bt2) ) { |
| 6025 | + type = type2; |
| 6026 | + } else if (is_float(bt1) && is_float(bt2)) { |
| 6005 | 6027 | if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { |
| 6006 | 6028 | type.t = VT_LDOUBLE; |
| 6007 | 6029 | |
| @@ -6010,56 +6032,65 @@ static void expr_cond(void) · 2 unmodified lines |
| 6010 | 6032 | } else { |
| 6011 | 6033 | type.t = VT_FLOAT; |
| 6012 | 6034 | } |
| 6013 | | − } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { |
| 6035 | + } else if ((bt1 == VT_LLONG && is_integer_btype(bt2)) || |
| 6036 | + (bt2 == VT_LLONG && is_integer_btype(bt1))) { |
| 6014 | 6037 | /* cast to biggest op */ |
| 6015 | 6038 | type.t = VT_LLONG | VT_LONG; |
| 6016 | | − if (bt1 == VT_LLONG) |
| 6039 | + if ( bt1 == VT_LLONG ) |
| 6017 | 6040 | type.t &= t1; |
| 6018 | | − if (bt2 == VT_LLONG) |
| 6041 | + if ( bt2 == VT_LLONG ) |
| 6019 | 6042 | type.t &= t2; |
| 6020 | 6043 | /* convert to unsigned if it does not fit in a long long */ |
| 6021 | 6044 | if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) || |
| 6022 | 6045 | (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED)) |
| 6023 | 6046 | type.t |= VT_UNSIGNED; |
| 6024 | | − } else if (bt1 == VT_PTR || bt2 == VT_PTR) { |
| 6025 | | − /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */ |
| 6026 | | − /* If one is a null ptr constant the result type |
| 6027 | | − is the other. */ |
| 6028 | | − if (is_null_pointer (vtop)) type = type1; |
| 6029 | | − else if (is_null_pointer (&sv)) type = type2; |
| 6030 | | − else if (bt1 != bt2) |
| 6031 | | − tcc_error("incompatible types in conditional expressions"); |
| 6032 | | − else { |
| 6033 | | − CType *pt1 = pointed_type(&type1); |
| 6034 | | − CType *pt2 = pointed_type(&type2); |
| 6035 | | − int pbt1 = pt1->t & VT_BTYPE; |
| 6036 | | − int pbt2 = pt2->t & VT_BTYPE; |
| 6037 | | − int newquals, copied = 0; |
| 6038 | | − /* pointers to void get preferred, otherwise the |
| 6039 | | − pointed to types minus qualifs should be compatible */ |
| 6040 | | − type = (pbt1 == VT_VOID) ? type1 : type2; |
| 6041 | | − if (pbt1 != VT_VOID && pbt2 != VT_VOID) { |
| 6042 | | − if(!compare_types(pt1, pt2, 1/*unqualif*/)) |
| 6043 | | − tcc_warning("pointer type mismatch in conditional expression\n"); |
| 6044 | | − } |
| 6045 | | − /* combine qualifs */ |
| 6046 | | − newquals = ((pt1->t | pt2->t) & (VT_CONSTANT | VT_VOLATILE)); |
| 6047 | | − if ((~pointed_type(&type)->t & (VT_CONSTANT | VT_VOLATILE)) |
| 6047 | + } |
| 6048 | + /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */ |
| 6049 | + /* If one is a null ptr constant the result type |
| 6050 | + is the other. */ |
| 6051 | + else if ( bt1 == VT_PTR && is_null_pointer(vtop) ) { |
| 6052 | + type = type1; |
| 6053 | + } else if ( is_null_pointer(&sv) && bt2 == VT_PTR ) { |
| 6054 | + type = type2; |
| 6055 | + } else if ( bt1 == VT_PTR && is_integer_btype(bt2) ) { |
| 6056 | + type = type1; |
| 6057 | + tcc_warning("pointer/integer mismatch"); |
| 6058 | + } else if ( is_integer_btype(bt1) && bt2 == VT_PTR ) { |
| 6059 | + type = type2; |
| 6060 | + tcc_warning("pointer/integer mismatch"); |
| 6061 | + } else if ( bt1==VT_PTR && bt2 == VT_PTR ) { |
| 6062 | + CType *pt1 = pointed_type(&type1); |
| 6063 | + CType *pt2 = pointed_type(&type2); |
| 6064 | + int pbt1 = pt1->t & VT_BTYPE; |
| 6065 | + int pbt2 = pt2->t & VT_BTYPE; |
| 6066 | + int newquals, copied = 0; |
| 6067 | + /* pointers to void get preferred, otherwise the |
| 6068 | + pointed to types minus qualifs should be compatible */ |
| 6069 | + type = (pbt1 == VT_VOID) ? type1 : type2; |
| 6070 | + if (pbt1 != VT_VOID && pbt2 != VT_VOID && ! compare_types(pt1, pt2, 1/*unqualif*/) ) { |
| 6071 | + type_incompatibility_warning(&type1, &type2, "incompatible pointer types"); |
| 6072 | + // result is void* |
| 6073 | + type.t = VT_VOID; |
| 6074 | + mk_pointer(&type); |
| 6075 | + } |
| 6076 | + /* combine qualifs */ |
| 6077 | + newquals = ((pt1->t | pt2->t) & (VT_CONSTANT | VT_VOLATILE)); |
| 6078 | + if ((~pointed_type(&type)->t & (VT_CONSTANT | VT_VOLATILE)) |
| 6048 | 6079 | & newquals) |
| 6049 | | − { |
| 6080 | + { |
| 6050 | 6081 | /* copy the pointer target symbol */ |
| 6051 | 6082 | type.ref = sym_push(SYM_FIELD, &type.ref->type, |
| 6052 | 6083 | 0, type.ref->c); |
| 6053 | 6084 | copied = 1; |
| 6054 | 6085 | pointed_type(&type)->t |= newquals; |
| 6055 | | − } |
| 6056 | | − /* pointers to incomplete arrays get converted to |
| 6057 | | − pointers to completed ones if possible */ |
| 6058 | | − if (pt1->t & VT_ARRAY |
| 6086 | + } |
| 6087 | + /* pointers to incomplete arrays get converted to |
| 6088 | + pointers to completed ones if possible */ |
| 6089 | + if (pt1->t & VT_ARRAY |
| 6059 | 6090 | && pt2->t & VT_ARRAY |
| 6060 | 6091 | && pointed_type(&type)->ref->c < 0 |
| 6061 | 6092 | && (pt1->ref->c > 0 || pt2->ref->c > 0)) |
| 6062 | | − { |
| 6093 | + { |
| 6063 | 6094 | if (!copied) |
| 6064 | 6095 | type.ref = sym_push(SYM_FIELD, &type.ref->type, |
| 6065 | 6096 | 0, type.ref->c); |
| @@ -6068,19 +6099,25 @@ static void expr_cond(void) · 2 unmodified lines |
| 6068 | 6099 | 0, pointed_type(&type)->ref->c); |
| 6069 | 6100 | pointed_type(&type)->ref->c = |
| 6070 | 6101 | 0 < pt1->ref->c ? pt1->ref->c : pt2->ref->c; |
| 6071 | | − } |
| 6102 | + } |
| 6103 | + } else if (bt1 == VT_STRUCT && bt2 == VT_STRUCT) { |
| 6104 | + /* test structure compatibility */ |
| 6105 | + if ( type1.ref != type2.ref ) { |
| 6106 | + type_incompatibility_error(&type1, &type2,"different struct/union types '%s' vs. '%s'"); |
| 6107 | + } else { |
| 6108 | + type = bt1 == VT_STRUCT ? type1 : type2; |
| 6072 | 6109 | } |
| 6073 | | − } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { |
| 6074 | | − /* XXX: test structure compatibility */ |
| 6075 | | − type = bt1 == VT_STRUCT ? type1 : type2; |
| 6076 | | − } else { |
| 6110 | + } else if ( is_integer_btype(bt1) && is_integer_btype(bt2) ) { |
| 6077 | 6111 | /* integer operations */ |
| 6078 | 6112 | type.t = VT_INT | (VT_LONG & (t1 | t2)); |
| 6079 | | − /* convert to unsigned if it does not fit in an integer */ |
| 6113 | + /* convert to unsigned if one of both is unsigned */ |
| 6080 | 6114 | if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) || |
| 6081 | 6115 | (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED)) |
| 6082 | 6116 | type.t |= VT_UNSIGNED; |
| 6117 | + } else { |
| 6118 | + type_incompatibility_error(&type1, &type2, "type '%s' is incompatible to '%s'"); |
| 6083 | 6119 | } |
| 6120 | + |
| 6084 | 6121 | /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so |
| 6085 | 6122 | that `(expr ? a : b).mem` does not error with "lvalue expected" */ |
| 6086 | 6123 | islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE); |