authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-04-07 23:34:30+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-04-08 00:27:14+03:00
logff0f97a1bcab4d27212c67b0ebc6233adf2f0de9
treedef7d8a41a2821eefc613fdec76c77aaf9c2fd7f
parented23dad4877cd93fd684852b17e0e554ef71e297
signaturelock-open Commit is signed but in an unrecognized format.

fix missing compile error on assign to slice and array parameters


4 files changed, 58 insertions(+), 4 deletions(-)

build.zig+3-2
......@@ -225,10 +225,11 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
225225 if (fs.path.isAbsolute(lib_arg)) {
226226 try result.libs.append(lib_arg);
227227 } else {
228 var lib_arg_copy = lib_arg;
228229 if (mem.endsWith(u8, lib_arg, ".lib")) {
229 lib_arg = lib_arg[0 .. lib_arg.len - 4];
230 lib_arg_copy = lib_arg[0 .. lib_arg.len - 4];
230231 }
231 try result.system_libs.append(lib_arg);
232 try result.system_libs.append(lib_arg_copy);
232233 }
233234 }
234235 }
src/ir.cpp+18-1
......@@ -27175,6 +27175,16 @@ done_with_return_type:
2717527175 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
2717627176 return result_loc;
2717727177 }
27178
27179 if (result_loc->value->type->id == ZigTypeIdPointer &&
27180 result_loc->value->type->data.pointer.is_const &&
27181 instruction->result_loc->id == ResultLocIdInstruction &&
27182 !instruction->result_loc->allow_write_through_const)
27183 {
27184 ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant"));
27185 return ira->codegen->invalid_inst_gen;
27186 }
27187
2717827188 IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type);
2717927189 dummy_value->value->special = ConstValSpecialRuntime;
2718027190 IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base,
......@@ -29908,8 +29918,15 @@ static IrInstGen *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstSrcEndEx
2990829918 return result_loc;
2990929919
2991029920 if (!was_written || instruction->result_loc->id == ResultLocIdPeer) {
29921 bool can_write_to_const_ptr = true;
29922 if (result_loc->value->type->id == ZigTypeIdPointer &&
29923 result_loc->value->type->data.pointer.is_const &&
29924 instruction->result_loc->id == ResultLocIdInstruction)
29925 {
29926 can_write_to_const_ptr = false;
29927 }
2991129928 IrInstGen *store_ptr = ir_analyze_store_ptr(ira, &instruction->base.base, result_loc, value,
29912 instruction->result_loc->allow_write_through_const);
29929 instruction->result_loc->allow_write_through_const && can_write_to_const_ptr);
2991329930 if (type_is_invalid(store_ptr->value->type)) {
2991429931 return ira->codegen->invalid_inst_gen;
2991529932 }
test/compile_errors.zig+36
......@@ -2,6 +2,42 @@ const tests = @import("tests.zig");
22const std = @import("std");
33
44pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.addTest("reassign to array parameter",
6 \\fn reassign(a: [3]f32) void {
7 \\ a = [3]f32{4, 5, 6};
8 \\}
9 \\export fn entry() void {
10 \\ reassign(.{1, 2, 3});
11 \\}
12 , &[_][]const u8{
13 "tmp.zig:2:16: error: cannot assign to constant"
14 });
15
16 cases.addTest("reassign to slice parameter",
17 \\pub fn reassign(s: []const u8) void {
18 \\ s = s[0..];
19 \\}
20 \\export fn entry() void {
21 \\ reassign("foo");
22 \\}
23 , &[_][]const u8{
24 "tmp.zig:2:10: error: cannot assign to constant"
25 });
26
27 cases.addTest("reassign to struct parameter",
28 \\const S = struct {
29 \\ x: u32,
30 \\};
31 \\fn reassign(s: S) void {
32 \\ s = S{.x = 2};
33 \\}
34 \\export fn entry() void {
35 \\ reassign(S{.x = 3});
36 \\}
37 , &[_][]const u8{
38 "tmp.zig:5:16: error: cannot assign to constant"
39 });
40
541 cases.addTest("reference to const data",
642 \\export fn foo() void {
743 \\ var ptr = &[_]u8{0,0,0,0};
test/tests.zig+1-1
......@@ -612,7 +612,7 @@ pub const StackTracesContext = struct {
612612
613613 const stdout = child.stdout.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable;
614614 defer b.allocator.free(stdout);
615 const stderr = child.stderr.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable;
615 var stderr = child.stderr.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable;
616616 defer b.allocator.free(stderr);
617617
618618 const term = child.wait() catch |err| {