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 {...@@ -225,10 +225,11 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
225 if (fs.path.isAbsolute(lib_arg)) {225 if (fs.path.isAbsolute(lib_arg)) {
226 try result.libs.append(lib_arg);226 try result.libs.append(lib_arg);
227 } else {227 } else {
228 var lib_arg_copy = lib_arg;
228 if (mem.endsWith(u8, lib_arg, ".lib")) {229 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];
230 }231 }
231 try result.system_libs.append(lib_arg);232 try result.system_libs.append(lib_arg_copy);
232 }233 }
233 }234 }
234 }235 }
src/ir.cpp+18-1
...@@ -27175,6 +27175,16 @@ done_with_return_type:...@@ -27175,6 +27175,16 @@ done_with_return_type:
27175 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {27175 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
27176 return result_loc;27176 return result_loc;
27177 }27177 }
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
27178 IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type);27188 IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type);
27179 dummy_value->value->special = ConstValSpecialRuntime;27189 dummy_value->value->special = ConstValSpecialRuntime;
27180 IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base,27190 IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base,
...@@ -29908,8 +29918,15 @@ static IrInstGen *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstSrcEndEx...@@ -29908,8 +29918,15 @@ static IrInstGen *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstSrcEndEx
29908 return result_loc;29918 return result_loc;
2990929919
29910 if (!was_written || instruction->result_loc->id == ResultLocIdPeer) {29920 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 }
29911 IrInstGen *store_ptr = ir_analyze_store_ptr(ira, &instruction->base.base, result_loc, value,29928 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);
29913 if (type_is_invalid(store_ptr->value->type)) {29930 if (type_is_invalid(store_ptr->value->type)) {
29914 return ira->codegen->invalid_inst_gen;29931 return ira->codegen->invalid_inst_gen;
29915 }29932 }
test/compile_errors.zig+36
...@@ -2,6 +2,42 @@ const tests = @import("tests.zig");...@@ -2,6 +2,42 @@ const tests = @import("tests.zig");
2const std = @import("std");2const std = @import("std");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub 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
5 cases.addTest("reference to const data",41 cases.addTest("reference to const data",
6 \\export fn foo() void {42 \\export fn foo() void {
7 \\ var ptr = &[_]u8{0,0,0,0};43 \\ var ptr = &[_]u8{0,0,0,0};
test/tests.zig+1-1
...@@ -612,7 +612,7 @@ pub const StackTracesContext = struct {...@@ -612,7 +612,7 @@ pub const StackTracesContext = struct {
612612
613 const stdout = child.stdout.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable;613 const stdout = child.stdout.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable;
614 defer b.allocator.free(stdout);614 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;
616 defer b.allocator.free(stderr);616 defer b.allocator.free(stderr);
617617
618 const term = child.wait() catch |err| {618 const term = child.wait() catch |err| {