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