Commit ff0f97a1bc
Changed files (4)
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;
}
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};
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| {
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);
}
}
}