| ... | ... | @@ -951,20 +951,47 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo |
| 951 | 951 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_PtrMemI"); |
| 952 | 952 | return nullptr; |
| 953 | 953 | case BO_Mul: |
| 954 | | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Mul"); |
| 955 | | return nullptr; |
| 954 | return trans_create_bin_op(c, block, stmt->getLHS(), |
| 955 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult, |
| 956 | stmt->getRHS()); |
| 956 | 957 | case BO_Div: |
| 957 | | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Div"); |
| 958 | | return nullptr; |
| 958 | if (qual_type_has_wrapping_overflow(c, stmt->getType())) { |
| 959 | // unsigned/float division uses the operator |
| 960 | return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeDiv, stmt->getRHS()); |
| 961 | } else { |
| 962 | // signed integer division uses @divTrunc |
| 963 | AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "divTrunc"); |
| 964 | AstNode *lhs = trans_expr(c, true, block, stmt->getLHS(), TransLValue); |
| 965 | if (lhs == nullptr) return nullptr; |
| 966 | fn_call->data.fn_call_expr.params.append(lhs); |
| 967 | AstNode *rhs = trans_expr(c, true, block, stmt->getRHS(), TransLValue); |
| 968 | if (rhs == nullptr) return nullptr; |
| 969 | fn_call->data.fn_call_expr.params.append(rhs); |
| 970 | return fn_call; |
| 971 | } |
| 959 | 972 | case BO_Rem: |
| 960 | | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Rem"); |
| 961 | | return nullptr; |
| 973 | if (qual_type_has_wrapping_overflow(c, stmt->getType())) { |
| 974 | // unsigned/float division uses the operator |
| 975 | return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeMod, stmt->getRHS()); |
| 976 | } else { |
| 977 | // signed integer division uses @divTrunc |
| 978 | AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "rem"); |
| 979 | AstNode *lhs = trans_expr(c, true, block, stmt->getLHS(), TransLValue); |
| 980 | if (lhs == nullptr) return nullptr; |
| 981 | fn_call->data.fn_call_expr.params.append(lhs); |
| 982 | AstNode *rhs = trans_expr(c, true, block, stmt->getRHS(), TransLValue); |
| 983 | if (rhs == nullptr) return nullptr; |
| 984 | fn_call->data.fn_call_expr.params.append(rhs); |
| 985 | return fn_call; |
| 986 | } |
| 962 | 987 | case BO_Add: |
| 963 | | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Add"); |
| 964 | | return nullptr; |
| 988 | return trans_create_bin_op(c, block, stmt->getLHS(), |
| 989 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd, |
| 990 | stmt->getRHS()); |
| 965 | 991 | case BO_Sub: |
| 966 | | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Sub"); |
| 967 | | return nullptr; |
| 992 | return trans_create_bin_op(c, block, stmt->getLHS(), |
| 993 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub, |
| 994 | stmt->getRHS()); |
| 968 | 995 | case BO_Shl: |
| 969 | 996 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Shl"); |
| 970 | 997 | return nullptr; |