fix crash when constant inside comptime function has compile error
closes #625
This commit is contained in:
parent
48ebb65cc7
commit
a2afcae9ff
@ -36,6 +36,7 @@ struct IrInstructionCast;
|
|||||||
struct IrBasicBlock;
|
struct IrBasicBlock;
|
||||||
struct ScopeDecls;
|
struct ScopeDecls;
|
||||||
struct ZigWindowsSDK;
|
struct ZigWindowsSDK;
|
||||||
|
struct Tld;
|
||||||
|
|
||||||
struct IrGotoItem {
|
struct IrGotoItem {
|
||||||
AstNode *source_node;
|
AstNode *source_node;
|
||||||
@ -59,7 +60,9 @@ struct IrExecutable {
|
|||||||
Buf *c_import_buf;
|
Buf *c_import_buf;
|
||||||
AstNode *source_node;
|
AstNode *source_node;
|
||||||
IrExecutable *parent_exec;
|
IrExecutable *parent_exec;
|
||||||
|
IrExecutable *source_exec;
|
||||||
Scope *begin_scope;
|
Scope *begin_scope;
|
||||||
|
ZigList<Tld *> tld_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OutType {
|
enum OutType {
|
||||||
|
27
src/ir.cpp
27
src/ir.cpp
@ -6332,6 +6332,9 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,
|
|||||||
}
|
}
|
||||||
irb->codegen->resolve_queue.append(&tld_container->base);
|
irb->codegen->resolve_queue.append(&tld_container->base);
|
||||||
|
|
||||||
|
// Add this to the list to mark as invalid if analyzing this exec fails.
|
||||||
|
irb->exec->tld_list.append(&tld_container->base);
|
||||||
|
|
||||||
return ir_build_const_type(irb, parent_scope, node, container_type);
|
return ir_build_const_type(irb, parent_scope, node, container_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6554,6 +6557,20 @@ static bool ir_goto_pass2(IrBuilder *irb) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void invalidate_exec(IrExecutable *exec) {
|
||||||
|
if (exec->invalid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
exec->invalid = true;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < exec->tld_list.length; i += 1) {
|
||||||
|
exec->tld_list.items[i]->resolution = TldResolutionInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exec->source_exec != nullptr)
|
||||||
|
invalidate_exec(exec->source_exec);
|
||||||
|
}
|
||||||
|
|
||||||
bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) {
|
bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) {
|
||||||
assert(node->owner);
|
assert(node->owner);
|
||||||
|
|
||||||
@ -6577,7 +6594,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ir_goto_pass2(irb)) {
|
if (!ir_goto_pass2(irb)) {
|
||||||
irb->exec->invalid = true;
|
invalidate_exec(ir_executable);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6603,7 +6620,7 @@ static void add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) {
|
static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) {
|
||||||
exec->invalid = true;
|
invalidate_exec(exec);
|
||||||
ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
|
ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
|
||||||
if (exec->parent_exec) {
|
if (exec->parent_exec) {
|
||||||
add_call_stack_errors(codegen, exec, err_msg, 10);
|
add_call_stack_errors(codegen, exec, err_msg, 10);
|
||||||
@ -8056,6 +8073,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
|
|||||||
IrExecutable analyzed_executable = {0};
|
IrExecutable analyzed_executable = {0};
|
||||||
analyzed_executable.source_node = source_node;
|
analyzed_executable.source_node = source_node;
|
||||||
analyzed_executable.parent_exec = parent_exec;
|
analyzed_executable.parent_exec = parent_exec;
|
||||||
|
analyzed_executable.source_exec = &ir_executable;
|
||||||
analyzed_executable.name = exec_name;
|
analyzed_executable.name = exec_name;
|
||||||
analyzed_executable.is_inline = true;
|
analyzed_executable.is_inline = true;
|
||||||
analyzed_executable.fn_entry = fn_entry;
|
analyzed_executable.fn_entry = fn_entry;
|
||||||
@ -10490,10 +10508,11 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
|
|||||||
result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,
|
result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,
|
||||||
ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry,
|
ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry,
|
||||||
nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec);
|
nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec);
|
||||||
if (type_is_invalid(result->value.type))
|
|
||||||
return ira->codegen->builtin_types.entry_invalid;
|
|
||||||
|
|
||||||
ira->codegen->memoized_fn_eval_table.put(exec_scope, result);
|
ira->codegen->memoized_fn_eval_table.put(exec_scope, result);
|
||||||
|
|
||||||
|
if (type_is_invalid(result->value.type))
|
||||||
|
return ira->codegen->builtin_types.entry_invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstExprValue *out_val = ir_build_const_from(ira, &call_instruction->base);
|
ConstExprValue *out_val = ir_build_const_from(ira, &call_instruction->base);
|
||||||
|
@ -2343,4 +2343,23 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
|
|||||||
\\pub extern fn foo(format: &const u8, ...);
|
\\pub extern fn foo(format: &const u8, ...);
|
||||||
,
|
,
|
||||||
".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");
|
".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");
|
||||||
|
|
||||||
|
cases.add("constant inside comptime function has compile error",
|
||||||
|
\\const ContextAllocator = MemoryPool(usize);
|
||||||
|
\\
|
||||||
|
\\pub fn MemoryPool(comptime T: type) -> type {
|
||||||
|
\\ const free_list_t = @compileError("aoeu");
|
||||||
|
\\
|
||||||
|
\\ struct {
|
||||||
|
\\ free_list: free_list_t,
|
||||||
|
\\ }
|
||||||
|
\\}
|
||||||
|
\\
|
||||||
|
\\export fn entry() {
|
||||||
|
\\ var allocator: ContextAllocator = undefined;
|
||||||
|
\\}
|
||||||
|
,
|
||||||
|
".tmp_source.zig:4:25: error: aoeu",
|
||||||
|
".tmp_source.zig:1:36: note: called from here",
|
||||||
|
".tmp_source.zig:12:20: note: referenced here");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user