authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-25 18:16:33-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-25 18:16:33-05:00
loga2afcae9ff1f2eed5c6a19a2bd63af288b9171ad
tree14778ba4c1e3151888ca209dd06b4ba72d545569
parent48ebb65cc7a976599c0a2b9e6647ea057727cf21

fix crash when constant inside comptime function has compile error

closes #625

3 files changed, 45 insertions(+), 4 deletions(-)

src/all_types.hpp+3
...@@ -36,6 +36,7 @@ struct IrInstructionCast;...@@ -36,6 +36,7 @@ struct IrInstructionCast;
36struct IrBasicBlock;36struct IrBasicBlock;
37struct ScopeDecls;37struct ScopeDecls;
38struct ZigWindowsSDK;38struct ZigWindowsSDK;
39struct Tld;
3940
40struct IrGotoItem {41struct IrGotoItem {
41 AstNode *source_node;42 AstNode *source_node;
...@@ -59,7 +60,9 @@ struct IrExecutable {...@@ -59,7 +60,9 @@ struct IrExecutable {
59 Buf *c_import_buf;60 Buf *c_import_buf;
60 AstNode *source_node;61 AstNode *source_node;
61 IrExecutable *parent_exec;62 IrExecutable *parent_exec;
63 IrExecutable *source_exec;
62 Scope *begin_scope;64 Scope *begin_scope;
65 ZigList<Tld *> tld_list;
63};66};
6467
65enum OutType {68enum OutType {
src/ir.cpp+23-4
...@@ -6332,6 +6332,9 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,...@@ -6332,6 +6332,9 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,
6332 }6332 }
6333 irb->codegen->resolve_queue.append(&tld_container->base);6333 irb->codegen->resolve_queue.append(&tld_container->base);
63346334
6335 // Add this to the list to mark as invalid if analyzing this exec fails.
6336 irb->exec->tld_list.append(&tld_container->base);
6337
6335 return ir_build_const_type(irb, parent_scope, node, container_type);6338 return ir_build_const_type(irb, parent_scope, node, container_type);
6336}6339}
63376340
...@@ -6554,6 +6557,20 @@ static bool ir_goto_pass2(IrBuilder *irb) {...@@ -6554,6 +6557,20 @@ static bool ir_goto_pass2(IrBuilder *irb) {
6554 return true;6557 return true;
6555}6558}
65566559
6560static void invalidate_exec(IrExecutable *exec) {
6561 if (exec->invalid)
6562 return;
6563
6564 exec->invalid = true;
6565
6566 for (size_t i = 0; i < exec->tld_list.length; i += 1) {
6567 exec->tld_list.items[i]->resolution = TldResolutionInvalid;
6568 }
6569
6570 if (exec->source_exec != nullptr)
6571 invalidate_exec(exec->source_exec);
6572}
6573
6557bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) {6574bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) {
6558 assert(node->owner);6575 assert(node->owner);
65596576
...@@ -6577,7 +6594,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -6577,7 +6594,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6577 }6594 }
65786595
6579 if (!ir_goto_pass2(irb)) {6596 if (!ir_goto_pass2(irb)) {
6580 irb->exec->invalid = true;6597 invalidate_exec(ir_executable);
6581 return false;6598 return false;
6582 }6599 }
65836600
...@@ -6603,7 +6620,7 @@ static void add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg...@@ -6603,7 +6620,7 @@ static void add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg
6603}6620}
66046621
6605static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) {6622static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) {
6606 exec->invalid = true;6623 invalidate_exec(exec);
6607 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);6624 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
6608 if (exec->parent_exec) {6625 if (exec->parent_exec) {
6609 add_call_stack_errors(codegen, exec, err_msg, 10);6626 add_call_stack_errors(codegen, exec, err_msg, 10);
...@@ -8056,6 +8073,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node...@@ -8056,6 +8073,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
8056 IrExecutable analyzed_executable = {0};8073 IrExecutable analyzed_executable = {0};
8057 analyzed_executable.source_node = source_node;8074 analyzed_executable.source_node = source_node;
8058 analyzed_executable.parent_exec = parent_exec;8075 analyzed_executable.parent_exec = parent_exec;
8076 analyzed_executable.source_exec = &ir_executable;
8059 analyzed_executable.name = exec_name;8077 analyzed_executable.name = exec_name;
8060 analyzed_executable.is_inline = true;8078 analyzed_executable.is_inline = true;
8061 analyzed_executable.fn_entry = fn_entry;8079 analyzed_executable.fn_entry = fn_entry;
...@@ -10490,10 +10508,11 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -10490,10 +10508,11 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
10490 result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,10508 result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,
10491 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry,10509 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry,
10492 nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec);10510 nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec);
10493 if (type_is_invalid(result->value.type))
10494 return ira->codegen->builtin_types.entry_invalid;
1049510511
10496 ira->codegen->memoized_fn_eval_table.put(exec_scope, result);10512 ira->codegen->memoized_fn_eval_table.put(exec_scope, result);
10513
10514 if (type_is_invalid(result->value.type))
10515 return ira->codegen->builtin_types.entry_invalid;
10497 }10516 }
1049810517
10499 ConstExprValue *out_val = ir_build_const_from(ira, &call_instruction->base);10518 ConstExprValue *out_val = ir_build_const_from(ira, &call_instruction->base);
test/compile_errors.zig+19
...@@ -2343,4 +2343,23 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2343,4 +2343,23 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2343 \\pub extern fn foo(format: &const u8, ...);2343 \\pub extern fn foo(format: &const u8, ...);
2344 ,2344 ,
2345 ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");2345 ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");
2346
2347 cases.add("constant inside comptime function has compile error",
2348 \\const ContextAllocator = MemoryPool(usize);
2349 \\
2350 \\pub fn MemoryPool(comptime T: type) -> type {
2351 \\ const free_list_t = @compileError("aoeu");
2352 \\
2353 \\ struct {
2354 \\ free_list: free_list_t,
2355 \\ }
2356 \\}
2357 \\
2358 \\export fn entry() {
2359 \\ var allocator: ContextAllocator = undefined;
2360 \\}
2361 ,
2362 ".tmp_source.zig:4:25: error: aoeu",
2363 ".tmp_source.zig:1:36: note: called from here",
2364 ".tmp_source.zig:12:20: note: referenced here");
2346}2365}