mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-13 09:22:22 -07:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
+42
-27
@@ -285,7 +285,7 @@ gb_internal void error_operand_no_value(Operand *o) {
|
||||
if (o->mode == Addressing_NoValue) {
|
||||
Ast *x = unparen_expr(o->expr);
|
||||
|
||||
if (x->kind == Ast_CallExpr) {
|
||||
if (x != nullptr && x->kind == Ast_CallExpr) {
|
||||
Ast *p = unparen_expr(x->CallExpr.proc);
|
||||
if (p->kind == Ast_BasicDirective) {
|
||||
String tag = p->BasicDirective.name.string;
|
||||
@@ -297,7 +297,7 @@ gb_internal void error_operand_no_value(Operand *o) {
|
||||
}
|
||||
|
||||
gbString err = expr_to_string(o->expr);
|
||||
if (x->kind == Ast_CallExpr) {
|
||||
if (x != nullptr && x->kind == Ast_CallExpr) {
|
||||
error(o->expr, "'%s' call does not return a value and cannot be used as a value", err);
|
||||
} else {
|
||||
error(o->expr, "'%s' used as a value", err);
|
||||
@@ -3612,10 +3612,11 @@ gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type
|
||||
if (are_types_identical(src_bt, dst_bt)) {
|
||||
return true;
|
||||
}
|
||||
if (is_type_integer(src_t) && is_type_integer(dst_t)) {
|
||||
if ((is_type_integer(src_t) && is_type_integer(dst_t)) ||
|
||||
is_type_integer(src_t) && is_type_bit_set(dst_t)) {
|
||||
if (types_have_same_internal_endian(src_t, dst_t)) {
|
||||
ExactValue src_v = exact_value_to_integer(o->value);
|
||||
GB_ASSERT(src_v.kind == ExactValue_Integer);
|
||||
GB_ASSERT(src_v.kind == ExactValue_Integer || src_v.kind == ExactValue_Invalid);
|
||||
BigInt v = src_v.value_integer;
|
||||
|
||||
BigInt smax = {};
|
||||
@@ -3900,6 +3901,12 @@ gb_internal void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Typ
|
||||
// IMPORTANT NOTE(bill): This uses right-left evaluation in type checking only no in
|
||||
check_expr(c, y, be->right);
|
||||
Type *rhs_type = type_deref(y->type);
|
||||
if (rhs_type == nullptr) {
|
||||
error(y->expr, "Cannot use '%.*s' on an expression with no value", LIT(op.string));
|
||||
x->mode = Addressing_Invalid;
|
||||
x->expr = node;
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_type_bit_set(rhs_type)) {
|
||||
Type *elem = base_type(rhs_type)->BitSet.elem;
|
||||
@@ -4602,7 +4609,7 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
|
||||
(operand->value.kind == ExactValue_Integer ||
|
||||
operand->value.kind == ExactValue_Float)) {
|
||||
operand->mode = Addressing_Value;
|
||||
target_type = t_untyped_nil;
|
||||
// target_type = t_untyped_nil;
|
||||
operand->value = empty_exact_value;
|
||||
update_untyped_expr_value(c, operand->expr, operand->value);
|
||||
break;
|
||||
@@ -6203,22 +6210,6 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
|
||||
|
||||
Entity *vt = pt->params->Tuple.variables[pt->variadic_index];
|
||||
o.type = vt->type;
|
||||
|
||||
// NOTE(bill, 2024-07-14): minimize the stack usage for variadic parameters with the backing array
|
||||
if (c->decl) {
|
||||
bool found = false;
|
||||
for (auto &vr : c->decl->variadic_reuses) {
|
||||
if (are_types_identical(vt->type, vr.slice_type)) {
|
||||
vr.max_count = gb_max(vr.max_count, variadic_operands.count);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
array_add(&c->decl->variadic_reuses, VariadicReuseData{vt->type, variadic_operands.count});
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
dummy_argument_count += 1;
|
||||
o.type = t_untyped_nil;
|
||||
@@ -6412,6 +6403,23 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
|
||||
}
|
||||
score += eval_param_and_score(c, o, t, err, true, var_entity, show_error);
|
||||
}
|
||||
|
||||
if (!vari_expand && variadic_operands.count != 0) {
|
||||
// NOTE(bill, 2024-07-14): minimize the stack usage for variadic parameters with the backing array
|
||||
if (c->decl) {
|
||||
bool found = false;
|
||||
for (auto &vr : c->decl->variadic_reuses) {
|
||||
if (are_types_identical(slice, vr.slice_type)) {
|
||||
vr.max_count = gb_max(vr.max_count, variadic_operands.count);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
array_add(&c->decl->variadic_reuses, VariadicReuseData{slice, variadic_operands.count});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data) {
|
||||
@@ -7807,7 +7815,8 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
||||
name == "load" ||
|
||||
name == "load_directory" ||
|
||||
name == "load_hash" ||
|
||||
name == "hash"
|
||||
name == "hash" ||
|
||||
name == "caller_expression"
|
||||
) {
|
||||
operand->mode = Addressing_Builtin;
|
||||
operand->builtin_id = BuiltinProc_DIRECTIVE;
|
||||
@@ -8087,7 +8096,10 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
||||
GB_ASSERT(c->curr_proc_decl->entity->type->kind == Type_Proc);
|
||||
String scope_features = c->curr_proc_decl->entity->type->Proc.enable_target_feature;
|
||||
if (!check_target_feature_is_superset_of(scope_features, pt->Proc.enable_target_feature, &invalid)) {
|
||||
ERROR_BLOCK();
|
||||
error(call, "Inlined procedure enables target feature '%.*s', this requires the calling procedure to at least enable the same feature", LIT(invalid));
|
||||
|
||||
error_line("\tSuggested Example: @(enable_target_feature=\"%.*s\")\n", LIT(invalid));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8722,6 +8734,10 @@ gb_internal ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, A
|
||||
error(node, "#caller_location may only be used as a default argument parameter");
|
||||
o->type = t_source_code_location;
|
||||
o->mode = Addressing_Value;
|
||||
} else if (name == "caller_expression") {
|
||||
error(node, "#caller_expression may only be used as a default argument parameter");
|
||||
o->type = t_string;
|
||||
o->mode = Addressing_Value;
|
||||
} else {
|
||||
if (name == "location") {
|
||||
init_core_source_code_location(c->checker);
|
||||
@@ -8787,11 +8803,6 @@ gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *n
|
||||
return kind;
|
||||
}
|
||||
|
||||
if (x.type == nullptr || x.type == t_invalid ||
|
||||
y.type == nullptr || y.type == t_invalid) {
|
||||
return kind;
|
||||
}
|
||||
|
||||
bool use_type_hint = type_hint != nullptr && (is_operand_nil(x) || is_operand_nil(y));
|
||||
|
||||
convert_to_typed(c, &x, use_type_hint ? type_hint : y.type);
|
||||
@@ -9123,6 +9134,10 @@ gb_internal ExprKind check_or_branch_expr(CheckerContext *c, Operand *o, Ast *no
|
||||
}
|
||||
|
||||
if (label != nullptr) {
|
||||
if (c->in_defer) {
|
||||
error(label, "A labelled '%.*s' cannot be used within a 'defer'", LIT(name));
|
||||
return Expr_Expr;
|
||||
}
|
||||
if (label->kind != Ast_Ident) {
|
||||
error(label, "A branch statement's label name must be an identifier");
|
||||
return Expr_Expr;
|
||||
|
||||
Reference in New Issue
Block a user