Fix ~(1 << x) type inference bug

This commit is contained in:
gingerBill
2019-08-23 10:24:18 +01:00
parent 4369298e96
commit 150d4e343d
2 changed files with 11 additions and 8 deletions
+10 -7
View File
@@ -1767,7 +1767,7 @@ void check_comparison(CheckerContext *c, Operand *x, Operand *y, TokenKind op) {
} }
void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node) { void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node, Type *type_hint) {
GB_ASSERT(node->kind == Ast_BinaryExpr); GB_ASSERT(node->kind == Ast_BinaryExpr);
ast_node(be, BinaryExpr, node); ast_node(be, BinaryExpr, node);
@@ -1845,6 +1845,9 @@ void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node) {
info->is_lhs = true; info->is_lhs = true;
} }
x->mode = Addressing_Value; x->mode = Addressing_Value;
if (type_hint && is_type_integer(type_hint)) {
x->type = type_hint;
}
// x->value = x_val; // x->value = x_val;
return; return;
} }
@@ -2167,7 +2170,7 @@ bool check_binary_array_expr(CheckerContext *c, Token op, Operand *x, Operand *y
} }
void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, bool use_lhs_as_type_hint=false) { void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint, bool use_lhs_as_type_hint=false) {
GB_ASSERT(node->kind == Ast_BinaryExpr); GB_ASSERT(node->kind == Ast_BinaryExpr);
Operand y_ = {}, *y = &y_; Operand y_ = {}, *y = &y_;
@@ -2178,7 +2181,7 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, bool use_lhs_as
case Token_CmpEq: case Token_CmpEq:
case Token_NotEq: { case Token_NotEq: {
// NOTE(bill): Allow comparisons between types // NOTE(bill): Allow comparisons between types
check_expr_or_type(c, x, be->left); check_expr_or_type(c, x, be->left, type_hint);
check_expr_or_type(c, y, be->right, x->type); check_expr_or_type(c, y, be->right, x->type);
bool xt = x->mode == Addressing_Type; bool xt = x->mode == Addressing_Type;
bool yt = y->mode == Addressing_Type; bool yt = y->mode == Addressing_Type;
@@ -2278,11 +2281,11 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, bool use_lhs_as
return; return;
default: default:
check_expr(c, x, be->left); check_expr_with_type_hint(c, x, be->left, type_hint);
if (use_lhs_as_type_hint) { if (use_lhs_as_type_hint) {
check_expr_with_type_hint(c, y, be->right, x->type); check_expr_with_type_hint(c, y, be->right, x->type);
} else { } else {
check_expr(c, y, be->right); check_expr_with_type_hint(c, y, be->right, type_hint);
} }
break; break;
} }
@@ -2307,7 +2310,7 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, bool use_lhs_as
} }
if (token_is_shift(op.kind)) { if (token_is_shift(op.kind)) {
check_shift(c, x, y, node); check_shift(c, x, y, node, type_hint);
return; return;
} }
@@ -7000,7 +7003,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
case_ast_node(be, BinaryExpr, node); case_ast_node(be, BinaryExpr, node);
check_binary_expr(c, o, node, true); check_binary_expr(c, o, node, type_hint, true);
if (o->mode == Addressing_Invalid) { if (o->mode == Addressing_Invalid) {
o->expr = node; o->expr = node;
return kind; return kind;
+1 -1
View File
@@ -1168,7 +1168,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
be->right = as->rhs[0]; be->right = as->rhs[0];
check_expr(ctx, &lhs, as->lhs[0]); check_expr(ctx, &lhs, as->lhs[0]);
check_binary_expr(ctx, &rhs, &binary_expr, true); check_binary_expr(ctx, &rhs, &binary_expr, nullptr, true);
if (rhs.mode == Addressing_Invalid) { if (rhs.mode == Addressing_Invalid) {
return; return;
} }