mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
ir: Avoid invalidating the decl_table iterator
Collect the declarations to resolve first and run resolve_top_level_decl on them later. Closes #4310
This commit is contained in:
parent
59a243ce24
commit
6b74fd2e12
45
src/ir.cpp
45
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,18 +23669,38 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
|
||||
// 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 the declaration is unresolved, force it to be resolved again.
|
||||
if (curr_entry->value->resolution == TldResolutionUnresolved)
|
||||
resolve_decl_queue.append(curr_entry->value);
|
||||
}
|
||||
|
||||
declaration_count += 1;
|
||||
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)
|
||||
continue;
|
||||
|
||||
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>();
|
||||
declaration_array->special = ConstValSpecialStatic;
|
||||
declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count, nullptr);
|
||||
|
||||
@ -3,13 +3,13 @@ const builtin = @import("builtin");
|
||||
const Target = @import("std").Target;
|
||||
|
||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
cases.addTest("access of undefined pointer to array",
|
||||
\\const ram_u32: *[4096]u32 = undefined;
|
||||
\\export fn entry() void {
|
||||
\\ @ptrCast(*u32, &(ram_u32[0])) = &(ram_u32[0]);
|
||||
cases.addTest("",
|
||||
\\const A = B;
|
||||
\\test "Crash" {
|
||||
\\ _ = @typeInfo(@This()).Struct.decls;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:3:29: error: use of undefined value here causes undefined behavior",
|
||||
"tmp.zig:1:11: error: use of undeclared identifier 'B'",
|
||||
});
|
||||
|
||||
cases.addTest("duplicate field in anonymous struct literal",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user