better handling for infinite loop prevention with overloads
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 2 Jun 2021 23:53:12 +0000 (18:53 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 2 Jun 2021 23:53:12 +0000 (18:53 -0500)
bin/onyx
include/onyxutils.h
src/onyxchecker.c
src/onyxutils.c

index d2adfee361dafc9e740178955b5aa1ec001fe424..5369eee0cf0636f33b3ef2fe28a9a29be9dad1cb 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index b9c9b21944ed3282b1687a9f2374a63f73c44404..0dc7f8bc6b46074b5ebf706d155dffec2b08098c 100644 (file)
@@ -26,6 +26,8 @@ AstNode* symbol_resolve(Scope* start_scope, OnyxToken* tkn);
 AstNode* try_symbol_raw_resolve_from_node(AstNode* node, char* symbol);
 AstNode* try_symbol_resolve_from_node(AstNode* node, OnyxToken* token);
 
+void build_all_overload_options(bh_arr(AstTyped *) overloads, bh_imap* all_overloads);
+
 u32 char_to_base16_value(char x);
 
 // Returns the length after processing the string.
index 28f15d85b9e9d8c93044063953265d64340a7b5b..041cace80f7e7a5da2b76f66d41978b582aafe2a 100644 (file)
@@ -1062,7 +1062,9 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) {
         CHECK(expression, actual);
 
         // HACK HACK HACK
-        if ((*actual)->type == NULL && (*actual)->kind == Ast_Kind_Function) {
+        if ((*actual)->type == NULL &&
+            (*actual)->entity != NULL &&
+            (*actual)->entity->state <= Entity_State_Check_Types) {
             return Check_Yield_Macro;
         }
 
@@ -1618,23 +1620,30 @@ CheckStatus check_function(AstFunction* func) {
 CheckStatus check_overloaded_function(AstOverloadedFunction* func) {
     b32 done = 1;
 
-    bh_arr_each(AstTyped *, node, func->overloads) {
-        if (   (*node)->kind != Ast_Kind_Function
-            && (*node)->kind != Ast_Kind_Polymorphic_Proc
-            && (*node)->kind != Ast_Kind_Overloaded_Function) {
-            onyx_report_error((*node)->token->pos, "Overload option not procedure. Got '%s'",
-                onyx_ast_node_kind_string((*node)->kind));
+    bh_imap all_overloads;
+    bh_imap_init(&all_overloads, global_heap_allocator, 4);
+    build_all_overload_options(func->overloads, &all_overloads);
 
+    bh_arr_each(bh__imap_entry, entry, all_overloads.entries) {
+        AstTyped* node = (AstTyped *) entry->key;
+        if (node->kind == Ast_Kind_Overloaded_Function) continue;
+
+        if (   node->kind != Ast_Kind_Function
+            && node->kind != Ast_Kind_Polymorphic_Proc) {
+            onyx_report_error(node->token->pos, "Overload option not procedure. Got '%s'",
+                onyx_ast_node_kind_string(node->kind));
+
+            bh_imap_free(&all_overloads);
             return Check_Error;
         }
 
-        if ((*node)->entity &&
-            (*node)->entity->type != Entity_Type_Overloaded_Function &&
-            (*node)->entity->state <= Entity_State_Check_Types) {
+        if (node->entity && node->entity->state <= Entity_State_Check_Types) {
             done = 0;
         }
     }
 
+    bh_imap_free(&all_overloads);
+
     if (done) return Check_Success;
     else      return Check_Yield_Macro;
 }
index 18bdc5aa255b042df6dacef3462cc812aed2c111..6717d882bb2decd643a3409675b5e8e8cde88235 100644 (file)
@@ -974,7 +974,7 @@ AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupM
 // an "entries" array that, so long as nothing is ever removed from it, will maintain the order in
 // which entries were put into the map. This is useful because a simple recursive algorithm can
 // collect all the overloads into the map, and also use the map to provide a base case.
-static void build_all_overload_options(bh_arr(AstTyped *) overloads, bh_imap* all_overloads) {
+void build_all_overload_options(bh_arr(AstTyped *) overloads, bh_imap* all_overloads) {
     bh_arr_each(AstTyped *, node, overloads) {
         if (bh_imap_has(all_overloads, (u64) *node)) continue;