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 ba11d4f1e9a508333be80f71bdf03a8cf0a1b1ad..29a4f06657396076607d1f6e9bef7b722cf0dea7 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -23556,10 +23556,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)) { @@ -23710,6 +23714,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, @@ -27179,6 +27188,13 @@ done_with_return_type: if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 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; + } + 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, diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 1d8f5e17f98e40c08ac09a521fe31d866480fc66..4a637fdc67c6f53a778b65c3496959b39cb4f16e 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:15: 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:10: 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| {