authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-08 13:44:57-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-08 13:44:57-04:00
logbfa1d12fbad2031402fbafe51c3a0c481fe69351
treeff1e8878a8f6dc8a7d70d0716b3ab1d94e51726d
parent8be95af48011f71f1902dff4ffbf5ea95cf1bcf4
signature Commit is signed but in an unrecognized format.

better compile errors when frame depends on itself


4 files changed, 49 insertions(+), 6 deletions(-)

src/analyze.cpp+8-3
...@@ -5179,11 +5179,14 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {...@@ -5179,11 +5179,14 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
5179 if (fn->anal_state == FnAnalStateInvalid)5179 if (fn->anal_state == FnAnalStateInvalid)
5180 return ErrorSemanticAnalyzeFail;5180 return ErrorSemanticAnalyzeFail;
5181 break;5181 break;
5182 case FnAnalStateProbing:5182 case FnAnalStateProbing: {
5183 add_node_error(g, fn->proto_node,5183 ErrorMsg *msg = add_node_error(g, fn->proto_node,
5184 buf_sprintf("cannot resolve '%s': function not fully analyzed yet",5184 buf_sprintf("cannot resolve '%s': function not fully analyzed yet",
5185 buf_ptr(&frame_type->name)));5185 buf_ptr(&frame_type->name)));
5186 ir_add_analysis_trace(fn->ir_executable.analysis, msg,
5187 buf_sprintf("depends on its own frame here"));
5186 return ErrorSemanticAnalyzeFail;5188 return ErrorSemanticAnalyzeFail;
5189 }
5187 }5190 }
5188 ZigType *fn_type = get_async_fn_type(g, fn->type_entry);5191 ZigType *fn_type = get_async_fn_type(g, fn->type_entry);
51895192
...@@ -5201,8 +5204,10 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {...@@ -5201,8 +5204,10 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
5201 if (callee->anal_state == FnAnalStateProbing) {5204 if (callee->anal_state == FnAnalStateProbing) {
5202 ErrorMsg *msg = add_node_error(g, fn->proto_node,5205 ErrorMsg *msg = add_node_error(g, fn->proto_node,
5203 buf_sprintf("unable to determine async function frame of '%s'", buf_ptr(&fn->symbol_name)));5206 buf_sprintf("unable to determine async function frame of '%s'", buf_ptr(&fn->symbol_name)));
5204 add_error_note(g, msg, call->base.source_node,5207 ErrorMsg *note = add_error_note(g, msg, call->base.source_node,
5205 buf_sprintf("analysis of function '%s' depends on the frame", buf_ptr(&callee->symbol_name)));5208 buf_sprintf("analysis of function '%s' depends on the frame", buf_ptr(&callee->symbol_name)));
5209 ir_add_analysis_trace(callee->ir_executable.analysis, note,
5210 buf_sprintf("depends on the frame here"));
5206 return ErrorSemanticAnalyzeFail;5211 return ErrorSemanticAnalyzeFail;
5207 }5212 }
52085213
src/ir.cpp+9-3
...@@ -8217,18 +8217,24 @@ bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) {...@@ -8217,18 +8217,24 @@ bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) {
8217 return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable);8217 return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable);
8218}8218}
82198219
8220static void add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) {8220static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) {
8221 if (!exec || !exec->source_node || limit < 0) return;8221 if (!exec || !exec->source_node || limit < 0) return;
8222 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here"));8222 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here"));
82238223
8224 add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1);8224 ir_add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1);
8225}
8226
8227void ir_add_analysis_trace(IrAnalyze *ira, ErrorMsg *err_msg, Buf *text) {
8228 IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);
8229 add_error_note(ira->codegen, err_msg, old_instruction->source_node, text);
8230 ir_add_call_stack_errors(ira->codegen, ira->new_irb.exec, err_msg, 10);
8225}8231}
82268232
8227static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) {8233static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) {
8228 invalidate_exec(exec);8234 invalidate_exec(exec);
8229 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);8235 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
8230 if (exec->parent_exec) {8236 if (exec->parent_exec) {
8231 add_call_stack_errors(codegen, exec, err_msg, 10);8237 ir_add_call_stack_errors(codegen, exec, err_msg, 10);
8232 }8238 }
8233 return err_msg;8239 return err_msg;
8234}8240}
src/ir.hpp+2
...@@ -28,4 +28,6 @@ ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprVal...@@ -28,4 +28,6 @@ ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprVal
28 AstNode *source_node);28 AstNode *source_node);
29const char *float_op_to_name(BuiltinFnId op, bool llvm_name);29const char *float_op_to_name(BuiltinFnId op, bool llvm_name);
3030
31void ir_add_analysis_trace(IrAnalyze *ira, ErrorMsg *err_msg, Buf *text);
32
31#endif33#endif
test/compile_errors.zig+30
...@@ -2,6 +2,36 @@ const tests = @import("tests.zig");...@@ -2,6 +2,36 @@ const tests = @import("tests.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add(
6 "async function indirectly depends on its own frame",
7 \\export fn entry() void {
8 \\ _ = async amain();
9 \\}
10 \\async fn amain() void {
11 \\ other();
12 \\}
13 \\fn other() void {
14 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;
15 \\}
16 ,
17 "tmp.zig:4:1: error: unable to determine async function frame of 'amain'",
18 "tmp.zig:5:10: note: analysis of function 'other' depends on the frame",
19 "tmp.zig:8:13: note: depends on the frame here",
20 );
21
22 cases.add(
23 "async function depends on its own frame",
24 \\export fn entry() void {
25 \\ _ = async amain();
26 \\}
27 \\async fn amain() void {
28 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;
29 \\}
30 ,
31 "tmp.zig:4:1: error: cannot resolve '@Frame(amain)': function not fully analyzed yet",
32 "tmp.zig:5:13: note: depends on its own frame here",
33 );
34
5 cases.add(35 cases.add(
6 "non async function pointer passed to @asyncCall",36 "non async function pointer passed to @asyncCall",
7 \\export fn entry() void {37 \\export fn entry() void {