| author | |
| committer | |
| log | 39207fa1d46ccaf55de80e1afd89fbccca6a73e7 |
| tree | adc43427b2ea4a30fba1cf12c5fa8117187ebe06 |
| parent | 7e549540527fec891bc67d5e657f82b7087530a3 |
| parent | c70ee9177e5b0095c152b66fe8f22cd870e778b9 |
| signature |
Deduplicate compile log statement warnings5 files changed, 94 insertions(+), 16 deletions(-)
src/all_types.hpp+1| ... | ... | @@ -648,6 +648,7 @@ struct AstNodeFnCallExpr { |
| 648 | 648 | ZigList<AstNode *> params; |
| 649 | 649 | bool is_builtin; |
| 650 | 650 | bool is_async; |
| 651 | bool seen; // used by @compileLog | |
| 651 | 652 | AstNode *async_allocator; |
| 652 | 653 | }; |
| 653 | 654 |
src/ir.cpp+7-3| ... | ... | @@ -17194,9 +17194,13 @@ static IrInstruction *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstr |
| 17194 | 17194 | } |
| 17195 | 17195 | fprintf(stderr, "\n"); |
| 17196 | 17196 | |
| 17197 | // Here we bypass higher level functions such as ir_add_error because we do not want | |
| 17198 | // invalidate_exec to be called. | |
| 17199 | add_node_error(ira->codegen, instruction->base.source_node, buf_sprintf("found compile log statement")); | |
| 17197 | auto *expr = &instruction->base.source_node->data.fn_call_expr; | |
| 17198 | if (!expr->seen) { | |
| 17199 | // Here we bypass higher level functions such as ir_add_error because we do not want | |
| 17200 | // invalidate_exec to be called. | |
| 17201 | add_node_error(ira->codegen, instruction->base.source_node, buf_sprintf("found compile log statement")); | |
| 17202 | } | |
| 17203 | expr->seen = true; | |
| 17200 | 17204 | |
| 17201 | 17205 | return ir_const_void(ira, &instruction->base); |
| 17202 | 17206 | } |
src/parser.cpp+2| ... | ... | @@ -2739,6 +2739,7 @@ static AstNode *ast_parse_async_prefix(ParseContext *pc) { |
| 2739 | 2739 | |
| 2740 | 2740 | AstNode *res = ast_create_node(pc, NodeTypeFnCallExpr, async); |
| 2741 | 2741 | res->data.fn_call_expr.is_async = true; |
| 2742 | res->data.fn_call_expr.seen = false; | |
| 2742 | 2743 | if (eat_token_if(pc, TokenIdCmpLessThan) != nullptr) { |
| 2743 | 2744 | AstNode *prefix_expr = ast_expect(pc, ast_parse_prefix_expr); |
| 2744 | 2745 | expect_token(pc, TokenIdCmpGreaterThan); |
| ... | ... | @@ -2759,6 +2760,7 @@ static AstNode *ast_parse_fn_call_argumnets(ParseContext *pc) { |
| 2759 | 2760 | |
| 2760 | 2761 | AstNode *res = ast_create_node(pc, NodeTypeFnCallExpr, paren); |
| 2761 | 2762 | res->data.fn_call_expr.params = params; |
| 2763 | res->data.fn_call_expr.seen = false; | |
| 2762 | 2764 | return res; |
| 2763 | 2765 | } |
| 2764 | 2766 |
test/compile_errors.zig+20-2| ... | ... | @@ -137,6 +137,24 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 137 | 137 | ".tmp_source.zig:3:15: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'", |
| 138 | 138 | ); |
| 139 | 139 | |
| 140 | cases.addCase(x: { | |
| 141 | var tc = cases.create( | |
| 142 | "compile log statement warning deduplication in generic fn", | |
| 143 | \\export fn entry() void { | |
| 144 | \\ inner(1); | |
| 145 | \\ inner(2); | |
| 146 | \\} | |
| 147 | \\fn inner(comptime n: usize) void { | |
| 148 | \\ comptime var i = 0; | |
| 149 | \\ inline while (i < n) : (i += 1) { @compileLog("!@#$"); } | |
| 150 | \\} | |
| 151 | , | |
| 152 | ".tmp_source.zig:7:39: error: found compile log statement", | |
| 153 | ); | |
| 154 | tc.expect_exact = true; | |
| 155 | break :x tc; | |
| 156 | }); | |
| 157 | ||
| 140 | 158 | cases.addTest( |
| 141 | 159 | "@truncate undefined value", |
| 142 | 160 | \\export fn entry() void { |
| ... | ... | @@ -4920,7 +4938,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4920 | 4938 | |
| 4921 | 4939 | cases.add( |
| 4922 | 4940 | "non-printable invalid character", |
| 4923 | "\xff\xfe" ++ | |
| 4941 | "\xff\xfe" ++ | |
| 4924 | 4942 | \\fn test() bool {\r |
| 4925 | 4943 | \\ true\r |
| 4926 | 4944 | \\} |
| ... | ... | @@ -5480,7 +5498,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5480 | 5498 | \\ Baz: void, |
| 5481 | 5499 | \\}; |
| 5482 | 5500 | \\comptime { |
| 5483 | \\ var foo = Foo {.Baz = {}}; | |
| 5501 | \\ var foo = Foo {.Baz = {}}; | |
| 5484 | 5502 | \\ const bar_val = foo.Bar; |
| 5485 | 5503 | \\} |
| 5486 | 5504 | , |
test/tests.zig+64-11| ... | ... | @@ -536,6 +536,7 @@ pub const CompileErrorContext = struct { |
| 536 | 536 | name: []const u8, |
| 537 | 537 | sources: ArrayList(SourceFile), |
| 538 | 538 | expected_errors: ArrayList([]const u8), |
| 539 | expect_exact: bool, | |
| 539 | 540 | link_libc: bool, |
| 540 | 541 | is_exe: bool, |
| 541 | 542 | is_test: bool, |
| ... | ... | @@ -565,6 +566,26 @@ pub const CompileErrorContext = struct { |
| 565 | 566 | case: *const TestCase, |
| 566 | 567 | build_mode: Mode, |
| 567 | 568 | |
| 569 | const ErrLineIter = struct { | |
| 570 | lines: mem.SplitIterator, | |
| 571 | ||
| 572 | const source_file = ".tmp_source.zig"; | |
| 573 | ||
| 574 | fn init(input: []const u8) ErrLineIter { | |
| 575 | return ErrLineIter { | |
| 576 | .lines = mem.separate(input, "\n"), | |
| 577 | }; | |
| 578 | } | |
| 579 | ||
| 580 | fn next(self: *ErrLineIter) ?[]const u8 { | |
| 581 | while (self.lines.next()) |line| { | |
| 582 | if (mem.indexOf(u8, line, source_file) != null) | |
| 583 | return line; | |
| 584 | } | |
| 585 | return null; | |
| 586 | } | |
| 587 | }; | |
| 588 | ||
| 568 | 589 | pub fn create(context: *CompileErrorContext, name: []const u8, case: *const TestCase, build_mode: Mode) *CompileCmpOutputStep { |
| 569 | 590 | const allocator = context.b.allocator; |
| 570 | 591 | const ptr = allocator.create(CompileCmpOutputStep) catch unreachable; |
| ... | ... | @@ -674,19 +695,50 @@ pub const CompileErrorContext = struct { |
| 674 | 695 | return error.TestFailed; |
| 675 | 696 | } |
| 676 | 697 | |
| 677 | for (self.case.expected_errors.toSliceConst()) |expected_error| { | |
| 678 | if (mem.indexOf(u8, stderr, expected_error) == null) { | |
| 679 | warn( | |
| 680 | \\ | |
| 681 | \\========= Expected this compile error: ========= | |
| 682 | \\{} | |
| 683 | \\================================================ | |
| 684 | \\{} | |
| 685 | \\ | |
| 686 | , expected_error, stderr); | |
| 687 | return error.TestFailed; | |
| 698 | var ok = true; | |
| 699 | if (self.case.expect_exact) { | |
| 700 | var err_iter = ErrLineIter.init(stderr); | |
| 701 | var i: usize = 0; | |
| 702 | ok = while (err_iter.next()) |line| : (i += 1) { | |
| 703 | if (i >= self.case.expected_errors.len) break false; | |
| 704 | const expected = self.case.expected_errors.at(i); | |
| 705 | if (mem.indexOf(u8, line, expected) == null) break false; | |
| 706 | continue; | |
| 707 | } else true; | |
| 708 | ||
| 709 | ok = ok and i == self.case.expected_errors.len; | |
| 710 | ||
| 711 | if (!ok) { | |
| 712 | warn("\n======== Expected these compile errors: ========\n"); | |
| 713 | for (self.case.expected_errors.toSliceConst()) |expected| { | |
| 714 | warn("{}\n", expected); | |
| 715 | } | |
| 716 | } | |
| 717 | } else { | |
| 718 | for (self.case.expected_errors.toSliceConst()) |expected| { | |
| 719 | if (mem.indexOf(u8, stderr, expected) == null) { | |
| 720 | warn( | |
| 721 | \\=========== Expected compile error: ============ | |
| 722 | \\{} | |
| 723 | \\ | |
| 724 | , expected | |
| 725 | ); | |
| 726 | ok = false; | |
| 727 | break; | |
| 728 | } | |
| 688 | 729 | } |
| 689 | 730 | } |
| 731 | ||
| 732 | if (!ok) { | |
| 733 | warn( | |
| 734 | \\================= Full output: ================= | |
| 735 | \\{} | |
| 736 | \\ | |
| 737 | , stderr | |
| 738 | ); | |
| 739 | return error.TestFailed; | |
| 740 | } | |
| 741 | ||
| 690 | 742 | warn("OK\n"); |
| 691 | 743 | } |
| 692 | 744 | }; |
| ... | ... | @@ -704,6 +756,7 @@ pub const CompileErrorContext = struct { |
| 704 | 756 | .name = name, |
| 705 | 757 | .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator), |
| 706 | 758 | .expected_errors = ArrayList([]const u8).init(self.b.allocator), |
| 759 | .expect_exact = false, | |
| 707 | 760 | .link_libc = false, |
| 708 | 761 | .is_exe = false, |
| 709 | 762 | .is_test = false, |