mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Fix ~(1 << x) type inference bug
This commit is contained in:
+10
-7
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user