mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Improve missing handled results for built in procedures
This commit is contained in:
+36
-10
@@ -1381,6 +1381,18 @@ bool all_operands_valid(Array<Operand> const &operands) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_stmt_internal_builtin_proc_id(Ast *expr, BuiltinProcId *id_) {
|
||||||
|
BuiltinProcId id = BuiltinProc_Invalid;
|
||||||
|
Entity *e = entity_of_node(expr);
|
||||||
|
if (e != nullptr && e->kind == Entity_Builtin) {
|
||||||
|
if (e->Builtin.id && e->Builtin.id != BuiltinProc_DIRECTIVE) {
|
||||||
|
id = cast(BuiltinProcId)e->Builtin.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (id_) *id_ = id;
|
||||||
|
return id != BuiltinProc_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
||||||
u32 mod_flags = flags & (~Stmt_FallthroughAllowed);
|
u32 mod_flags = flags & (~Stmt_FallthroughAllowed);
|
||||||
switch (node->kind) {
|
switch (node->kind) {
|
||||||
@@ -1408,26 +1420,40 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
|||||||
|
|
||||||
Ast *expr = strip_or_return_expr(operand.expr);
|
Ast *expr = strip_or_return_expr(operand.expr);
|
||||||
if (expr->kind == Ast_CallExpr) {
|
if (expr->kind == Ast_CallExpr) {
|
||||||
|
BuiltinProcId builtin_id = BuiltinProc_Invalid;
|
||||||
|
bool do_require = false;
|
||||||
|
|
||||||
AstCallExpr *ce = &expr->CallExpr;
|
AstCallExpr *ce = &expr->CallExpr;
|
||||||
Type *t = base_type(type_of_expr(ce->proc));
|
Type *t = base_type(type_of_expr(ce->proc));
|
||||||
if (t->kind == Type_Proc) {
|
if (t->kind == Type_Proc) {
|
||||||
if (t->Proc.require_results) {
|
do_require = t->Proc.require_results;
|
||||||
gbString expr_str = expr_to_string(ce->proc);
|
} else if (check_stmt_internal_builtin_proc_id(ce->proc, &builtin_id)) {
|
||||||
error(node, "'%s' requires that its results must be handled", expr_str);
|
auto const &bp = builtin_procs[builtin_id];
|
||||||
gb_string_free(expr_str);
|
do_require = bp.kind == Expr_Expr && !bp.ignore_results;
|
||||||
}
|
}
|
||||||
|
if (do_require) {
|
||||||
|
gbString expr_str = expr_to_string(ce->proc);
|
||||||
|
error(node, "'%s' requires that its results must be handled", expr_str);
|
||||||
|
gb_string_free(expr_str);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (expr->kind == Ast_SelectorCallExpr) {
|
} else if (expr->kind == Ast_SelectorCallExpr) {
|
||||||
|
BuiltinProcId builtin_id = BuiltinProc_Invalid;
|
||||||
|
bool do_require = false;
|
||||||
|
|
||||||
AstSelectorCallExpr *se = &expr->SelectorCallExpr;
|
AstSelectorCallExpr *se = &expr->SelectorCallExpr;
|
||||||
ast_node(ce, CallExpr, se->call);
|
ast_node(ce, CallExpr, se->call);
|
||||||
Type *t = base_type(type_of_expr(ce->proc));
|
Type *t = base_type(type_of_expr(ce->proc));
|
||||||
if (t->kind == Type_Proc) {
|
if (t->kind == Type_Proc) {
|
||||||
if (t->Proc.require_results) {
|
do_require = t->Proc.require_results;
|
||||||
gbString expr_str = expr_to_string(ce->proc);
|
} else if (check_stmt_internal_builtin_proc_id(ce->proc, &builtin_id)) {
|
||||||
error(node, "'%s' requires that its results must be handled", expr_str);
|
auto const &bp = builtin_procs[builtin_id];
|
||||||
gb_string_free(expr_str);
|
do_require = bp.kind == Expr_Expr && !bp.ignore_results;
|
||||||
}
|
}
|
||||||
|
if (do_require) {
|
||||||
|
gbString expr_str = expr_to_string(ce->proc);
|
||||||
|
error(node, "'%s' requires that its results must be handled", expr_str);
|
||||||
|
gb_string_free(expr_str);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ struct BuiltinProc {
|
|||||||
ExprKind kind;
|
ExprKind kind;
|
||||||
BuiltinProcPkg pkg;
|
BuiltinProcPkg pkg;
|
||||||
bool diverging;
|
bool diverging;
|
||||||
|
bool ignore_results; // ignores require results handling
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -385,26 +385,26 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
|||||||
{STR_LIT("atomic_signal_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_signal_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||||
{STR_LIT("atomic_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||||
{STR_LIT("atomic_store_explicit"), 3, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_store_explicit"), 3, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||||
{STR_LIT("atomic_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_load_explicit"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_load_explicit"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_add"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_add"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_add_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_add_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_sub_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_sub_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_and"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_and"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_and_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_and_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_nand"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_nand"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_nand_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_nand_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_or"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_or"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_or_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_or_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_xor"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_xor"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_xor_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_xor_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_exchange"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_exchange"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_exchange_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_exchange_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_compare_exchange_strong"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_compare_exchange_strong"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_compare_exchange_strong_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_compare_exchange_strong_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_compare_exchange_weak"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_compare_exchange_weak"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("atomic_compare_exchange_weak_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("atomic_compare_exchange_weak_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
|
|
||||||
{STR_LIT("fixed_point_mul"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("fixed_point_mul"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
{STR_LIT("fixed_point_div"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("fixed_point_div"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
@@ -477,7 +477,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
|||||||
{STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
{STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||||
|
|
||||||
|
|
||||||
{STR_LIT("syscall"), 1, true, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("syscall"), 1, true, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("x86_cpuid"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("x86_cpuid"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
{STR_LIT("x86_xgetbv"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("x86_xgetbv"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
|
|
||||||
@@ -565,12 +565,12 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
|||||||
|
|
||||||
{STR_LIT("__entry_point"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
{STR_LIT("__entry_point"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||||
|
|
||||||
{STR_LIT("objc_send"), 3, true, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("objc_send"), 3, true, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
|
|
||||||
{STR_LIT("objc_find_selector"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("objc_find_selector"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
{STR_LIT("objc_find_class"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("objc_find_class"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
{STR_LIT("objc_register_selector"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("objc_register_selector"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
{STR_LIT("objc_register_class"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("objc_register_class"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||||
|
|
||||||
{STR_LIT("constant_utf16_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("constant_utf16_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
|
|
||||||
|
|||||||
@@ -411,7 +411,6 @@ AST_KIND(_ExprBegin, "", bool) \
|
|||||||
Token ellipsis; \
|
Token ellipsis; \
|
||||||
ProcInlining inlining; \
|
ProcInlining inlining; \
|
||||||
bool optional_ok_one; \
|
bool optional_ok_one; \
|
||||||
i32 builtin_id; \
|
|
||||||
void *sce_temp_data; \
|
void *sce_temp_data; \
|
||||||
}) \
|
}) \
|
||||||
AST_KIND(FieldValue, "field value", struct { Token eq; Ast *field, *value; }) \
|
AST_KIND(FieldValue, "field value", struct { Token eq; Ast *field, *value; }) \
|
||||||
|
|||||||
Reference in New Issue
Block a user