| 3197 | //========================================================================== |
| 3198 | |
| 3199 | bool FxBinary::Promote(FCompileContext &ctx, bool forceint, bool shiftop) |
| 3200 | { |
| 3201 | // math operations of unsigned ints results in an unsigned int. (16 and 8 bit values never get here, they get promoted to regular ints elsewhere already.) |
| 3202 | if (left->ValueType == TypeUInt32 && right->ValueType == TypeUInt32) |
| 3203 | { |
| 3204 | ValueType = TypeUInt32; |
| 3205 | } |
| 3206 | // If one side is an unsigned 32-bit int and the other side is a signed 32-bit int, the signed side is implicitly converted to unsigned, |
| 3207 | else if (!ctx.FromDecorate && left->ValueType == TypeUInt32 && right->ValueType == TypeSInt32 && !shiftop && ctx.Version >= MakeVersion(4, 9, 0)) |
| 3208 | { |
| 3209 | right = new FxIntCast(right, false, false, true); |
| 3210 | right = right->Resolve(ctx); |
| 3211 | ValueType = TypeUInt32; |
| 3212 | } |
| 3213 | else if (!ctx.FromDecorate && left->ValueType == TypeSInt32 && right->ValueType == TypeUInt32 && !shiftop && ctx.Version >= MakeVersion(4, 9, 0)) |
| 3214 | { |
| 3215 | left = new FxIntCast(left, false, false, true); |
| 3216 | left = left->Resolve(ctx); |
| 3217 | ValueType = TypeUInt32; |
| 3218 | } |
| 3219 | else if (left->IsInteger() && right->IsInteger()) |
| 3220 | { |
| 3221 | ValueType = TypeSInt32; // Addition and subtraction forces all integer-derived types to signed int. |
| 3222 | } |
| 3223 | else if (!forceint) |
| 3224 | { |
| 3225 | ValueType = TypeFloat64; |
| 3226 | if (left->IsFloat() && right->IsInteger()) |
| 3227 | { |
| 3228 | right = (new FxFloatCast(right))->Resolve(ctx); |
| 3229 | } |
| 3230 | else if (left->IsInteger() && right->IsFloat()) |
| 3231 | { |
| 3232 | left = (new FxFloatCast(left))->Resolve(ctx); |
| 3233 | } |
| 3234 | } |
| 3235 | else if (ctx.FromDecorate) |
| 3236 | { |
| 3237 | // For DECORATE which allows floats here. ZScript does not. |
| 3238 | if (left->IsFloat()) |
| 3239 | { |
| 3240 | left = new FxIntCast(left, ctx.FromDecorate); |
| 3241 | left = left->Resolve(ctx); |
| 3242 | } |
| 3243 | if (right->IsFloat()) |
| 3244 | { |
| 3245 | right = new FxIntCast(right, ctx.FromDecorate); |
| 3246 | right = right->Resolve(ctx); |
| 3247 | } |
| 3248 | if (left == nullptr || right == nullptr) |
| 3249 | { |
| 3250 | delete this; |
| 3251 | return false; |
| 3252 | } |
| 3253 | ValueType = TypeSInt32; |
| 3254 | |
| 3255 | } |
| 3256 | else |
nothing calls this directly
no test coverage detected