diff options
| author | LemonBoy <thatlemon@gmail.com> | 2020-02-16 20:19:30 +0100 |
|---|---|---|
| committer | LemonBoy <thatlemon@gmail.com> | 2020-02-16 21:14:30 +0100 |
| commit | 6b74fd2e12b117e90197db5f4fa1ea51aa246248 (patch) | |
| tree | 495e7cb300694b5fdeb01065bc0c1b3b82e83118 /src/ir.cpp | |
| parent | 59a243ce24e858260d289c5c40f3430223b7d98b (diff) | |
| download | zig-6b74fd2e12b117e90197db5f4fa1ea51aa246248.tar.gz zig-6b74fd2e12b117e90197db5f4fa1ea51aa246248.zip | |
ir: Avoid invalidating the decl_table iterator
Collect the declarations to resolve first and run resolve_top_level_decl
on them later.
Closes #4310
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index a29a5b6948..8544fe1758 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -23653,14 +23653,13 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown))) return err; - // Loop through our declarations once to figure out how many declarations we will generate info for. + // The unresolved declarations are collected in a separate queue to avoid + // modifying decl_table while iterating over it + ZigList<Tld*> resolve_decl_queue{}; + auto decl_it = decls_scope->decl_table.entry_iterator(); decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; - int declaration_count = 0; - while ((curr_entry = decl_it.next()) != nullptr) { - // If the declaration is unresolved, force it to be resolved again. - resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false); if (curr_entry->value->resolution == TldResolutionInvalid) { return ErrorSemanticAnalyzeFail; } @@ -23670,16 +23669,36 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa return ErrorSemanticAnalyzeFail; } + // If the declaration is unresolved, force it to be resolved again. + if (curr_entry->value->resolution == TldResolutionUnresolved) + resolve_decl_queue.append(curr_entry->value); + } + + for (size_t i = 0; i < resolve_decl_queue.length; i++) { + Tld *decl = resolve_decl_queue.at(i); + resolve_top_level_decl(ira->codegen, decl, decl->source_node, false); + if (decl->resolution == TldResolutionInvalid) { + return ErrorSemanticAnalyzeFail; + } + } + + resolve_decl_queue.deinit(); + + // Loop through our declarations once to figure out how many declarations we will generate info for. + int declaration_count = 0; + decl_it = decls_scope->decl_table.entry_iterator(); + while ((curr_entry = decl_it.next()) != nullptr) { // Skip comptime blocks and test functions. - if (curr_entry->value->id != TldIdCompTime) { - if (curr_entry->value->id == TldIdFn) { - ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; - if (fn_entry->is_test) - continue; - } + if (curr_entry->value->id == TldIdCompTime) + continue; - declaration_count += 1; + if (curr_entry->value->id == TldIdFn) { + ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; + if (fn_entry->is_test) + continue; } + + declaration_count += 1; } ZigValue *declaration_array = ira->codegen->pass1_arena->create<ZigValue>(); |
