diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-12-18 20:52:40 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-12-18 20:52:40 -0500 |
| commit | 132e2fa5d9cc17088082cf4797701214c20845f1 (patch) | |
| tree | faf24be2d876da8ec77edcc5e5fa56b5217a7099 | |
| parent | cfc9f7422f3b0e4077eca42d7b71cd5523dad0a9 (diff) | |
| download | zig-132e2fa5d9cc17088082cf4797701214c20845f1.tar.gz zig-132e2fa5d9cc17088082cf4797701214c20845f1.zip | |
errors from inline fn calls include stack trace
| -rw-r--r-- | src/all_types.hpp | 2 | ||||
| -rw-r--r-- | src/analyze.cpp | 2 | ||||
| -rw-r--r-- | src/ir.cpp | 25 | ||||
| -rw-r--r-- | src/ir.hpp | 3 | ||||
| -rw-r--r-- | std/test_runner.zig | 4 |
5 files changed, 26 insertions, 10 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index 1a4a3fd694..b7dc70ed40 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -55,6 +55,8 @@ struct IrExecutable { bool is_inline; FnTableEntry *fn_entry; Buf *c_import_buf; + AstNode *source_node; + IrExecutable *parent_exec; }; enum OutType { diff --git a/src/analyze.cpp b/src/analyze.cpp index c42df80c7a..144d50a70c 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -875,7 +875,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *nod size_t backward_branch_count = 0; return ir_eval_const_value(g, scope, node, type_entry, &backward_branch_count, default_backward_branch_quota, - nullptr, nullptr, node, type_name); + nullptr, nullptr, node, type_name, nullptr); } TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { diff --git a/src/ir.cpp b/src/ir.cpp index 985994b41e..3bc0674b44 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4169,9 +4169,17 @@ IrInstruction *ir_gen_fn(CodeGen *codegen, FnTableEntry *fn_entry) { return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); } +static void add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) { + if (!exec || !exec->source_node || limit < 0) return; + add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); + add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1); +} + static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction, Buf *msg) { ira->new_irb.exec->invalid = true; - return add_node_error(ira->codegen, source_instruction->source_node, msg); + ErrorMsg *err_msg = add_node_error(ira->codegen, source_instruction->source_node, msg); + add_call_stack_errors(ira->codegen, ira->new_irb.exec, err_msg, 10); + return err_msg; } static IrInstruction *ir_exec_const_result(IrExecutable *exec) { @@ -4680,9 +4688,12 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, - FnTableEntry *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name) + FnTableEntry *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, + IrExecutable *parent_exec) { IrExecutable ir_executable = {0}; + ir_executable.source_node = source_node; + ir_executable.parent_exec = parent_exec; ir_executable.name = exec_name; ir_executable.is_inline = true; ir_executable.fn_entry = fn_entry; @@ -4700,6 +4711,8 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node fprintf(stderr, "}\n"); } IrExecutable analyzed_executable = {0}; + analyzed_executable.source_node = source_node; + analyzed_executable.parent_exec = parent_exec; analyzed_executable.name = exec_name; analyzed_executable.is_inline = true; analyzed_executable.fn_entry = fn_entry; @@ -4730,7 +4743,7 @@ static TypeTableEntry *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value return ira->codegen->builtin_types.entry_invalid; if (type_value->type_entry->id != TypeTableEntryIdMetaType) { - add_node_error(ira->codegen, type_value->source_node, + ir_add_error(ira, type_value, buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->type_entry->name))); return ira->codegen->builtin_types.entry_invalid; } @@ -5152,7 +5165,7 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ ImplicitCastMatchResult result = ir_types_match_with_implicit_cast(ira, expected_type, value->type_entry, value); switch (result) { case ImplicitCastMatchResultNo: - add_node_error(ira->codegen, first_executing_node(value->source_node), + ir_add_error(ira, value, buf_sprintf("expected type '%s', found '%s'", buf_ptr(&expected_type->name), buf_ptr(&value->type_entry->name))); @@ -6147,7 +6160,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body; 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, - nullptr, call_instruction->base.source_node, nullptr); + nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec); if (result->type_entry->id == TypeTableEntryIdInvalid) return ira->codegen->builtin_types.entry_invalid; @@ -8432,7 +8445,7 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc TypeTableEntry *void_type = ira->codegen->builtin_types.entry_void; IrInstruction *result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, - &cimport_scope->buf, block_node, nullptr); + &cimport_scope->buf, block_node, nullptr, nullptr); if (result->type_entry->id == TypeTableEntryIdInvalid) return ira->codegen->builtin_types.entry_invalid; diff --git a/src/ir.hpp b/src/ir.hpp index 69e8115bf8..b2044d0688 100644 --- a/src/ir.hpp +++ b/src/ir.hpp @@ -15,7 +15,8 @@ IrInstruction *ir_gen_fn(CodeGen *g, FnTableEntry *fn_entry); IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, - FnTableEntry *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name); + FnTableEntry *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, + IrExecutable *parent_exec); TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable, TypeTableEntry *expected_type, AstNode *expected_type_source_node); diff --git a/std/test_runner.zig b/std/test_runner.zig index 18dc5714aa..e80a061ff6 100644 --- a/std/test_runner.zig +++ b/std/test_runner.zig @@ -1,9 +1,9 @@ const io = @import("std").io; -struct TestFn { +const TestFn = struct { name: []u8, func: extern fn(), -} +}; extern var zig_test_fn_list: []TestFn; |
