mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Fix double calling of lhs of logical binary expressions
This commit is contained in:
+6
-2
@@ -62,7 +62,7 @@ Type * make_optional_ok_type (Type *value);
|
|||||||
void check_type_decl (CheckerContext *c, Entity *e, Ast *type_expr, Type *def);
|
void check_type_decl (CheckerContext *c, Entity *e, Ast *type_expr, Type *def);
|
||||||
Entity * check_selector (CheckerContext *c, Operand *operand, Ast *node, Type *type_hint);
|
Entity * check_selector (CheckerContext *c, Operand *operand, Ast *node, Type *type_hint);
|
||||||
Entity * check_ident (CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name);
|
Entity * check_ident (CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name);
|
||||||
Entity * find_polymorphic_record_entity (CheckerContext *c, Type *original_type, isize param_count, Array<Operand> ordered_operands);
|
Entity * find_polymorphic_record_entity (CheckerContext *c, Type *original_type, isize param_count, Array<Operand> const &ordered_operands, bool *failure);
|
||||||
void check_not_tuple (CheckerContext *c, Operand *operand);
|
void check_not_tuple (CheckerContext *c, Operand *operand);
|
||||||
void convert_to_typed (CheckerContext *c, Operand *operand, Type *target_type);
|
void convert_to_typed (CheckerContext *c, Operand *operand, Type *target_type);
|
||||||
gbString expr_to_string (Ast *expression);
|
gbString expr_to_string (Ast *expression);
|
||||||
@@ -6336,12 +6336,16 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper
|
|||||||
{
|
{
|
||||||
gbAllocator a = c->allocator;
|
gbAllocator a = c->allocator;
|
||||||
|
|
||||||
Entity *found_entity = find_polymorphic_record_entity(c, original_type, param_count, ordered_operands);
|
bool failure = false;
|
||||||
|
Entity *found_entity = find_polymorphic_record_entity(c, original_type, param_count, ordered_operands, &failure);
|
||||||
if (found_entity) {
|
if (found_entity) {
|
||||||
operand->mode = Addressing_Type;
|
operand->mode = Addressing_Type;
|
||||||
operand->type = found_entity->type;
|
operand->type = found_entity->type;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
if (failure) {
|
||||||
|
return CallArgumentError_NoneConstantParameter;
|
||||||
|
}
|
||||||
|
|
||||||
String generated_name = make_string_c(expr_to_string(call));
|
String generated_name = make_string_c(expr_to_string(call));
|
||||||
|
|
||||||
|
|||||||
+19
-10
@@ -248,38 +248,47 @@ bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, isize param_count, Array<Operand> ordered_operands) {
|
Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, isize param_count, Array<Operand> const &ordered_operands, bool *failure) {
|
||||||
auto *found_gen_types = map_get(&ctx->checker->info.gen_types, hash_pointer(original_type));
|
auto *found_gen_types = map_get(&ctx->checker->info.gen_types, hash_pointer(original_type));
|
||||||
if (found_gen_types != nullptr) {
|
if (found_gen_types != nullptr) {
|
||||||
for_array(i, *found_gen_types) {
|
for_array(i, *found_gen_types) {
|
||||||
Entity *e = (*found_gen_types)[i];
|
Entity *e = (*found_gen_types)[i];
|
||||||
Type *t = base_type(e->type);
|
Type *t = base_type(e->type);
|
||||||
TypeTuple *tuple = get_record_polymorphic_params(t);
|
TypeTuple *tuple = get_record_polymorphic_params(t);
|
||||||
bool ok = true;
|
|
||||||
GB_ASSERT(param_count == tuple->variables.count);
|
GB_ASSERT(param_count == tuple->variables.count);
|
||||||
|
|
||||||
|
bool skip = false;
|
||||||
|
|
||||||
for (isize j = 0; j < param_count; j++) {
|
for (isize j = 0; j < param_count; j++) {
|
||||||
Entity *p = tuple->variables[j];
|
Entity *p = tuple->variables[j];
|
||||||
Operand o = ordered_operands[j];
|
Operand o = ordered_operands[j];
|
||||||
if (p->kind == Entity_TypeName) {
|
if (p->kind == Entity_TypeName) {
|
||||||
if (is_type_polymorphic(o.type)) {
|
if (is_type_polymorphic(o.type)) {
|
||||||
// NOTE(bill): Do not add polymorphic version to the gen_types
|
// NOTE(bill): Do not add polymorphic version to the gen_types
|
||||||
ok = false;
|
skip = true;
|
||||||
}
|
break;
|
||||||
if (!are_types_identical(o.type, p->type)) {
|
} else if (!are_types_identical(o.type, p->type)) {
|
||||||
ok = false;
|
skip = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (p->kind == Entity_Constant) {
|
} else if (p->kind == Entity_Constant) {
|
||||||
if (!are_types_identical(o.type, p->type)) {
|
if (o.mode != Addressing_Constant) {
|
||||||
ok = false;
|
if (failure) *failure = true;
|
||||||
|
skip = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (!compare_exact_values(Token_CmpEq, o.value, p->Constant.value)) {
|
if (!compare_exact_values(Token_CmpEq, o.value, p->Constant.value)) {
|
||||||
ok = false;
|
skip = true;
|
||||||
|
break;
|
||||||
|
} else if (!are_types_identical(o.type, p->type)) {
|
||||||
|
skip = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GB_PANIC("Unknown entity kind");
|
GB_PANIC("Unknown entity kind");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ok) {
|
if (!skip) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-7
@@ -5647,7 +5647,8 @@ irValue *ir_emit_logical_binary_expr(irProcedure *proc, TokenKind op, Ast *left,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ir_start_block(proc, rhs);
|
ir_start_block(proc, rhs);
|
||||||
array_add(&edges, ir_build_expr(proc, right));
|
irValue *edge = ir_build_expr(proc, right);
|
||||||
|
array_add(&edges, edge);
|
||||||
ir_emit_jump(proc, done);
|
ir_emit_jump(proc, done);
|
||||||
ir_start_block(proc, done);
|
ir_start_block(proc, done);
|
||||||
|
|
||||||
@@ -5656,8 +5657,6 @@ irValue *ir_emit_logical_binary_expr(irProcedure *proc, TokenKind op, Ast *left,
|
|||||||
|
|
||||||
irValue *ir_emit_logical_binary_expr(irProcedure *proc, Ast *expr) {
|
irValue *ir_emit_logical_binary_expr(irProcedure *proc, Ast *expr) {
|
||||||
ast_node(be, BinaryExpr, expr);
|
ast_node(be, BinaryExpr, expr);
|
||||||
irBlock *rhs = ir_new_block(proc, nullptr, "logical.cmp.rhs");
|
|
||||||
irBlock *done = ir_new_block(proc, nullptr, "logical.cmp.done");
|
|
||||||
|
|
||||||
Type *type = type_of_expr(expr);
|
Type *type = type_of_expr(expr);
|
||||||
type = default_type(type);
|
type = default_type(type);
|
||||||
@@ -6879,9 +6878,6 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
|
|||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(be, BinaryExpr, expr);
|
case_ast_node(be, BinaryExpr, expr);
|
||||||
irValue *left = ir_build_expr(proc, be->left);
|
|
||||||
Type *type = default_type(tv.type);
|
|
||||||
|
|
||||||
switch (be->op.kind) {
|
switch (be->op.kind) {
|
||||||
case Token_Add:
|
case Token_Add:
|
||||||
case Token_Sub:
|
case Token_Sub:
|
||||||
@@ -6895,6 +6891,8 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
|
|||||||
case Token_AndNot:
|
case Token_AndNot:
|
||||||
case Token_Shl:
|
case Token_Shl:
|
||||||
case Token_Shr: {
|
case Token_Shr: {
|
||||||
|
irValue *left = ir_build_expr(proc, be->left);
|
||||||
|
Type *type = default_type(tv.type);
|
||||||
irValue *right = ir_build_expr(proc, be->right);
|
irValue *right = ir_build_expr(proc, be->right);
|
||||||
return ir_emit_arith(proc, be->op.kind, left, right, type);
|
return ir_emit_arith(proc, be->op.kind, left, right, type);
|
||||||
}
|
}
|
||||||
@@ -6906,10 +6904,11 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
|
|||||||
case Token_LtEq:
|
case Token_LtEq:
|
||||||
case Token_Gt:
|
case Token_Gt:
|
||||||
case Token_GtEq: {
|
case Token_GtEq: {
|
||||||
|
irValue *left = ir_build_expr(proc, be->left);
|
||||||
|
Type *type = default_type(tv.type);
|
||||||
irValue *right = ir_build_expr(proc, be->right);
|
irValue *right = ir_build_expr(proc, be->right);
|
||||||
irValue *cmp = ir_emit_comp(proc, be->op.kind, left, right);
|
irValue *cmp = ir_emit_comp(proc, be->op.kind, left, right);
|
||||||
return ir_emit_conv(proc, cmp, type);
|
return ir_emit_conv(proc, cmp, type);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Token_CmpAnd:
|
case Token_CmpAnd:
|
||||||
@@ -6919,6 +6918,8 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
|
|||||||
|
|
||||||
case Token_in:
|
case Token_in:
|
||||||
case Token_notin: {
|
case Token_notin: {
|
||||||
|
irValue *left = ir_build_expr(proc, be->left);
|
||||||
|
Type *type = default_type(tv.type);
|
||||||
irValue *right = ir_build_expr(proc, be->right);
|
irValue *right = ir_build_expr(proc, be->right);
|
||||||
Type *rt = base_type(ir_type(right));
|
Type *rt = base_type(ir_type(right));
|
||||||
switch (rt->kind) {
|
switch (rt->kind) {
|
||||||
|
|||||||
Reference in New Issue
Block a user