Browse Source

Improve missing handled results for built in procedures

gingerBill 3 years ago
parent
commit
f3868ac932
4 changed files with 61 additions and 35 deletions
  1. 36 10
      src/check_stmt.cpp
  2. 1 0
      src/checker.hpp
  3. 24 24
      src/checker_builtin_procs.hpp
  4. 0 1
      src/parser.hpp

+ 36 - 10
src/check_stmt.cpp

@@ -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) {
-						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);
-					}
+					do_require = t->Proc.require_results;
+				} else if (check_stmt_internal_builtin_proc_id(ce->proc, &builtin_id)) {
+					auto const &bp = builtin_procs[builtin_id];
+					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) {
-						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);
-					}
+					do_require = t->Proc.require_results;
+				} else if (check_stmt_internal_builtin_proc_id(ce->proc, &builtin_id)) {
+					auto const &bp = builtin_procs[builtin_id];
+					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;
 			}
 			}

+ 1 - 0
src/checker.hpp

@@ -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
 };
 };
 
 
 
 

+ 24 - 24
src/checker_builtin_procs.hpp

@@ -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_explicit"),                    2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_add"),                              2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_add_explicit"),                     3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_sub"),                              2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_sub_explicit"),                     3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_and"),                              2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_and_explicit"),                     3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_nand"),                             2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_nand_explicit"),                    3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_or"),                               2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_or_explicit"),                      3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_xor"),                              2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_xor_explicit"),                     3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_exchange"),                         2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_exchange_explicit"),                3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_compare_exchange_strong"),          3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_compare_exchange_strong_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_compare_exchange_weak"),            3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
-	{STR_LIT("atomic_compare_exchange_weak_explicit"),   5, 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, false, true},
+	{STR_LIT("atomic_add"),                              2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_add_explicit"),                     3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_sub"),                              2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_sub_explicit"),                     3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_and"),                              2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_and_explicit"),                     3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_nand"),                             2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_nand_explicit"),                    3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_or"),                               2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_or_explicit"),                      3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_xor"),                              2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_xor_explicit"),                     3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{STR_LIT("atomic_exchange"),                         2, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
+	{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, false, true},
+	{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, false, true},
+	{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_class"),    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, false, true},
 
 
 	{STR_LIT("constant_utf16_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 	{STR_LIT("constant_utf16_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 
 

+ 0 - 1
src/parser.hpp

@@ -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; }) \