authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-16 20:19:30+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-16 21:14:30+01:00
log6b74fd2e12b117e90197db5f4fa1ea51aa246248
tree495e7cb300694b5fdeb01065bc0c1b3b82e83118
parent59a243ce24e858260d289c5c40f3430223b7d98b

ir: Avoid invalidating the decl_table iterator

Collect the declarations to resolve first and run resolve_top_level_decl on them later. Closes #4310

2 files changed, 36 insertions(+), 17 deletions(-)

src/ir.cpp+31-12
...@@ -23653,14 +23653,13 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa...@@ -23653,14 +23653,13 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
23653 if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown)))23653 if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown)))
23654 return err;23654 return err;
2365523655
23656 // Loop through our declarations once to figure out how many declarations we will generate info for.23656 // The unresolved declarations are collected in a separate queue to avoid
23657 // modifying decl_table while iterating over it
23658 ZigList<Tld*> resolve_decl_queue{};
23659
23657 auto decl_it = decls_scope->decl_table.entry_iterator();23660 auto decl_it = decls_scope->decl_table.entry_iterator();
23658 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr;23661 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr;
23659 int declaration_count = 0;
23660
23661 while ((curr_entry = decl_it.next()) != nullptr) {23662 while ((curr_entry = decl_it.next()) != nullptr) {
23662 // If the declaration is unresolved, force it to be resolved again.
23663 resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false);
23664 if (curr_entry->value->resolution == TldResolutionInvalid) {23663 if (curr_entry->value->resolution == TldResolutionInvalid) {
23665 return ErrorSemanticAnalyzeFail;23664 return ErrorSemanticAnalyzeFail;
23666 }23665 }
...@@ -23670,16 +23669,36 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa...@@ -23670,16 +23669,36 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
23670 return ErrorSemanticAnalyzeFail;23669 return ErrorSemanticAnalyzeFail;
23671 }23670 }
2367223671
23672 // If the declaration is unresolved, force it to be resolved again.
23673 if (curr_entry->value->resolution == TldResolutionUnresolved)
23674 resolve_decl_queue.append(curr_entry->value);
23675 }
23676
23677 for (size_t i = 0; i < resolve_decl_queue.length; i++) {
23678 Tld *decl = resolve_decl_queue.at(i);
23679 resolve_top_level_decl(ira->codegen, decl, decl->source_node, false);
23680 if (decl->resolution == TldResolutionInvalid) {
23681 return ErrorSemanticAnalyzeFail;
23682 }
23683 }
23684
23685 resolve_decl_queue.deinit();
23686
23687 // Loop through our declarations once to figure out how many declarations we will generate info for.
23688 int declaration_count = 0;
23689 decl_it = decls_scope->decl_table.entry_iterator();
23690 while ((curr_entry = decl_it.next()) != nullptr) {
23673 // Skip comptime blocks and test functions.23691 // Skip comptime blocks and test functions.
23674 if (curr_entry->value->id != TldIdCompTime) {23692 if (curr_entry->value->id == TldIdCompTime)
23675 if (curr_entry->value->id == TldIdFn) {23693 continue;
23676 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;
23677 if (fn_entry->is_test)
23678 continue;
23679 }
2368023694
23681 declaration_count += 1;23695 if (curr_entry->value->id == TldIdFn) {
23696 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;
23697 if (fn_entry->is_test)
23698 continue;
23682 }23699 }
23700
23701 declaration_count += 1;
23683 }23702 }
2368423703
23685 ZigValue *declaration_array = ira->codegen->pass1_arena->create<ZigValue>();23704 ZigValue *declaration_array = ira->codegen->pass1_arena->create<ZigValue>();
test/compile_errors.zig+5-5
...@@ -3,13 +3,13 @@ const builtin = @import("builtin");...@@ -3,13 +3,13 @@ const builtin = @import("builtin");
3const Target = @import("std").Target;3const Target = @import("std").Target;
44
5pub fn addCases(cases: *tests.CompileErrorContext) void {5pub fn addCases(cases: *tests.CompileErrorContext) void {
6 cases.addTest("access of undefined pointer to array",6 cases.addTest("",
7 \\const ram_u32: *[4096]u32 = undefined;7 \\const A = B;
8 \\export fn entry() void {8 \\test "Crash" {
9 \\ @ptrCast(*u32, &(ram_u32[0])) = &(ram_u32[0]);9 \\ _ = @typeInfo(@This()).Struct.decls;
10 \\}10 \\}
11 , &[_][]const u8{11 , &[_][]const u8{
12 "tmp.zig:3:29: error: use of undefined value here causes undefined behavior",12 "tmp.zig:1:11: error: use of undeclared identifier 'B'",
13 });13 });
1414
15 cases.addTest("duplicate field in anonymous struct literal",15 cases.addTest("duplicate field in anonymous struct literal",