| author | |
| committer | |
| log | 079728752eca4cffbb4f7e8dc06d5e23b81d7627 |
| tree | 552dcf5837bf1b3f4cab297bed4a9e0e0bea4c0f |
| parent | 067968c57f2c7ed4f0606913aa608f6c2be418d2 |
| signature |
closes #1113 files changed, 38 insertions(+), 8 deletions(-)
src/ir.cpp+18-1| ... | ... | @@ -3674,6 +3674,22 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode |
| 3674 | 3674 | return ir_build_const_null(irb, scope, node); |
| 3675 | 3675 | } |
| 3676 | 3676 | |
| 3677 | static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode *node, Buf *var_name) { | |
| 3678 | ScopeDecls *scope_decls = nullptr; | |
| 3679 | while (scope != nullptr) { | |
| 3680 | if (scope->id == ScopeIdDecls) { | |
| 3681 | scope_decls = reinterpret_cast<ScopeDecls *>(scope); | |
| 3682 | } | |
| 3683 | scope = scope->parent; | |
| 3684 | } | |
| 3685 | TldVar *tld_var = allocate<TldVar>(1); | |
| 3686 | init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); | |
| 3687 | tld_var->base.resolution = TldResolutionInvalid; | |
| 3688 | tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, | |
| 3689 | &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid); | |
| 3690 | scope_decls->decl_table.put(var_name, &tld_var->base); | |
| 3691 | } | |
| 3692 | ||
| 3677 | 3693 | static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 3678 | 3694 | Error err; |
| 3679 | 3695 | assert(node->type == NodeTypeSymbol); |
| ... | ... | @@ -3727,8 +3743,9 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3727 | 3743 | return irb->codegen->invalid_instruction; |
| 3728 | 3744 | } |
| 3729 | 3745 | |
| 3730 | // TODO put a variable of same name with invalid type in global scope | |
| 3746 | // put a variable of same name with invalid type in global scope | |
| 3731 | 3747 | // so that future references to this same name will find a variable with an invalid type |
| 3748 | populate_invalid_variable_in_scope(irb->codegen, scope, node, variable_name); | |
| 3732 | 3749 | add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); |
| 3733 | 3750 | return irb->codegen->invalid_instruction; |
| 3734 | 3751 | } |
test/compile_errors.zig+18-6| ... | ... | @@ -1,6 +1,22 @@ |
| 1 | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | |
| 3 | 3 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4 | cases.addCase(x: { | |
| 5 | var tc = cases.create( | |
| 6 | "deduplicate undeclared identifier", | |
| 7 | \\export fn a() void { | |
| 8 | \\ x += 1; | |
| 9 | \\} | |
| 10 | \\export fn b() void { | |
| 11 | \\ x += 1; | |
| 12 | \\} | |
| 13 | , | |
| 14 | ".tmp_source.zig:2:5: error: use of undeclared identifier 'x'", | |
| 15 | ); | |
| 16 | tc.expect_exact = true; | |
| 17 | break :x tc; | |
| 18 | }); | |
| 19 | ||
| 4 | 20 | cases.addTest( |
| 5 | 21 | "export generic function", |
| 6 | 22 | \\export fn foo(num: var) i32 { |
| ... | ... | @@ -2280,7 +2296,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2280 | 2296 | \\} |
| 2281 | 2297 | , |
| 2282 | 2298 | ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'", |
| 2283 | ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'", | |
| 2284 | 2299 | ); |
| 2285 | 2300 | |
| 2286 | 2301 | cases.add( |
| ... | ... | @@ -5618,8 +5633,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5618 | 5633 | ".tmp_source.zig:2:26: error: vector element type must be integer, float, or pointer; '@Vector(4, u8)' is invalid", |
| 5619 | 5634 | ); |
| 5620 | 5635 | |
| 5621 | cases.add( | |
| 5622 | "compileLog of tagged enum doesn't crash the compiler", | |
| 5636 | cases.add("compileLog of tagged enum doesn't crash the compiler", | |
| 5623 | 5637 | \\const Bar = union(enum(u32)) { |
| 5624 | 5638 | \\ X: i32 = 1 |
| 5625 | 5639 | \\}; |
| ... | ... | @@ -5631,7 +5645,5 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5631 | 5645 | \\pub fn main () void { |
| 5632 | 5646 | \\ comptime testCompileLog(Bar{.X = 123}); |
| 5633 | 5647 | \\} |
| 5634 | , | |
| 5635 | ".tmp_source.zig:6:5: error: found compile log statement" | |
| 5636 | ); | |
| 5648 | , ".tmp_source.zig:6:5: error: found compile log statement"); | |
| 5637 | 5649 | } |
test/tests.zig+2-1| ... | ... | @@ -716,7 +716,8 @@ pub const CompileErrorContext = struct { |
| 716 | 716 | for (self.case.expected_errors.toSliceConst()) |expected| { |
| 717 | 717 | if (mem.indexOf(u8, stderr, expected) == null) { |
| 718 | 718 | warn( |
| 719 | \\\n=========== Expected compile error: ============ | |
| 719 | \\ | |
| 720 | \\=========== Expected compile error: ============ | |
| 720 | 721 | \\{} |
| 721 | 722 | \\ |
| 722 | 723 | , expected); |