From ff0f97a1bcab4d27212c67b0ebc6233adf2f0de9 Mon Sep 17 00:00:00 2001 From: Vexu Date: Tue, 7 Apr 2020 23:34:30 +0300 Subject: [PATCH 1/2] fix missing compile error on assign to slice and array parameters --- build.zig | 5 +++-- src/ir.cpp | 19 ++++++++++++++++++- test/compile_errors.zig | 36 ++++++++++++++++++++++++++++++++++++ test/tests.zig | 2 +- 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/build.zig b/build.zig index ba37c1aa4278bec51bc35d12687fd24d9e58b668..f6f929c72732a9aef1d4f7e1d1d0cfa07edfc303 100644 --- a/build.zig +++ b/build.zig @@ -225,10 +225,11 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep { if (fs.path.isAbsolute(lib_arg)) { try result.libs.append(lib_arg); } else { + var lib_arg_copy = lib_arg; if (mem.endsWith(u8, lib_arg, ".lib")) { - lib_arg = lib_arg[0 .. lib_arg.len - 4]; + lib_arg_copy = lib_arg[0 .. lib_arg.len - 4]; } - try result.system_libs.append(lib_arg); + try result.system_libs.append(lib_arg_copy); } } } diff --git a/src/ir.cpp b/src/ir.cpp index b57011717761477c6c994fbac3e43f030c42b6a9..7dbf365355118e25e42a44f2acadaa80e972bfc1 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -27175,6 +27175,16 @@ done_with_return_type: if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { return result_loc; } + + if (result_loc->value->type->id == ZigTypeIdPointer && + result_loc->value->type->data.pointer.is_const && + instruction->result_loc->id == ResultLocIdInstruction && + !instruction->result_loc->allow_write_through_const) + { + ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); + return ira->codegen->invalid_inst_gen; + } + IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type); dummy_value->value->special = ConstValSpecialRuntime; IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base, @@ -29908,8 +29918,15 @@ static IrInstGen *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstSrcEndEx return result_loc; if (!was_written || instruction->result_loc->id == ResultLocIdPeer) { + bool can_write_to_const_ptr = true; + if (result_loc->value->type->id == ZigTypeIdPointer && + result_loc->value->type->data.pointer.is_const && + instruction->result_loc->id == ResultLocIdInstruction) + { + can_write_to_const_ptr = false; + } IrInstGen *store_ptr = ir_analyze_store_ptr(ira, &instruction->base.base, result_loc, value, - instruction->result_loc->allow_write_through_const); + instruction->result_loc->allow_write_through_const && can_write_to_const_ptr); if (type_is_invalid(store_ptr->value->type)) { return ira->codegen->invalid_inst_gen; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 1d8f5e17f98e40c08ac09a521fe31d866480fc66..c966f8771df529f831d10682cb0f2f54b2a0bd93 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,42 @@ const tests = @import("tests.zig"); const std = @import("std"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.addTest("reassign to array parameter", + \\fn reassign(a: [3]f32) void { + \\ a = [3]f32{4, 5, 6}; + \\} + \\export fn entry() void { + \\ reassign(.{1, 2, 3}); + \\} + , &[_][]const u8{ + "tmp.zig:2:16: error: cannot assign to constant" + }); + + cases.addTest("reassign to slice parameter", + \\pub fn reassign(s: []const u8) void { + \\ s = s[0..]; + \\} + \\export fn entry() void { + \\ reassign("foo"); + \\} + , &[_][]const u8{ + "tmp.zig:2:10: error: cannot assign to constant" + }); + + cases.addTest("reassign to struct parameter", + \\const S = struct { + \\ x: u32, + \\}; + \\fn reassign(s: S) void { + \\ s = S{.x = 2}; + \\} + \\export fn entry() void { + \\ reassign(S{.x = 3}); + \\} + , &[_][]const u8{ + "tmp.zig:5:16: error: cannot assign to constant" + }); + cases.addTest("reference to const data", \\export fn foo() void { \\ var ptr = &[_]u8{0,0,0,0}; diff --git a/test/tests.zig b/test/tests.zig index d88c84502dc39753471108b9bd8a5f51d1e72e8a..59a0af195e1347c5b4c28a542936f17059d0ac7e 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -612,7 +612,7 @@ pub const StackTracesContext = struct { const stdout = child.stdout.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable; defer b.allocator.free(stdout); - const stderr = child.stderr.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable; + var stderr = child.stderr.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable; defer b.allocator.free(stderr); const term = child.wait() catch |err| { -- 2.54.0 From b1e44adcba55e3839a3676db83ff61c344f3bbad Mon Sep 17 00:00:00 2001 From: Vexu Date: Wed, 8 Apr 2020 14:20:05 +0300 Subject: [PATCH 2/2] move array and struct const checks to more appropriate places --- src/ir.cpp | 27 +++++++++++++-------------- test/compile_errors.zig | 4 ++-- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 7dbf365355118e25e42a44f2acadaa80e972bfc1..02a6536d95a166a0124da5d28e5285b225b597fc 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -23552,10 +23552,14 @@ static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira, IrInstGen *result_loc = instruction->result_loc->child; if (type_is_invalid(result_loc->value->type)) return result_loc; + ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); + if (result_loc->value->type->data.pointer.is_const) { + ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); + return ira->codegen->invalid_inst_gen; + } ZigType *container_type = result_loc->value->type->data.pointer.child_type; - size_t elem_count = instruction->item_count; if (is_slice(container_type)) { @@ -23706,6 +23710,11 @@ static IrInstGen *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, return result_loc; ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); + if (result_loc->value->type->data.pointer.is_const) { + ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); + return ira->codegen->invalid_inst_gen; + } + ZigType *container_type = result_loc->value->type->data.pointer.child_type; return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type, @@ -27176,11 +27185,8 @@ done_with_return_type: return result_loc; } - if (result_loc->value->type->id == ZigTypeIdPointer && - result_loc->value->type->data.pointer.is_const && - instruction->result_loc->id == ResultLocIdInstruction && - !instruction->result_loc->allow_write_through_const) - { + ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); + if (result_loc->value->type->data.pointer.is_const) { ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); return ira->codegen->invalid_inst_gen; } @@ -29918,15 +29924,8 @@ static IrInstGen *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstSrcEndEx return result_loc; if (!was_written || instruction->result_loc->id == ResultLocIdPeer) { - bool can_write_to_const_ptr = true; - if (result_loc->value->type->id == ZigTypeIdPointer && - result_loc->value->type->data.pointer.is_const && - instruction->result_loc->id == ResultLocIdInstruction) - { - can_write_to_const_ptr = false; - } IrInstGen *store_ptr = ir_analyze_store_ptr(ira, &instruction->base.base, result_loc, value, - instruction->result_loc->allow_write_through_const && can_write_to_const_ptr); + instruction->result_loc->allow_write_through_const); if (type_is_invalid(store_ptr->value->type)) { return ira->codegen->invalid_inst_gen; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index c966f8771df529f831d10682cb0f2f54b2a0bd93..4a637fdc67c6f53a778b65c3496959b39cb4f16e 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -10,7 +10,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ reassign(.{1, 2, 3}); \\} , &[_][]const u8{ - "tmp.zig:2:16: error: cannot assign to constant" + "tmp.zig:2:15: error: cannot assign to constant" }); cases.addTest("reassign to slice parameter", @@ -35,7 +35,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ reassign(S{.x = 3}); \\} , &[_][]const u8{ - "tmp.zig:5:16: error: cannot assign to constant" + "tmp.zig:5:10: error: cannot assign to constant" }); cases.addTest("reference to const data", -- 2.54.0