Skip to content

Commit beae932

Browse files
authored
Merge pull request #4975 from Vexu/param-reassign
Fix missing compile error on assign to slice and array parameters
2 parents c3afaa1 + b1e44ad commit beae932

File tree

4 files changed

+57
-4
lines changed

4 files changed

+57
-4
lines changed

build.zig

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23556,10 +23556,14 @@ static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
2355623556
IrInstGen *result_loc = instruction->result_loc->child;
2355723557
if (type_is_invalid(result_loc->value->type))
2355823558
return result_loc;
23559+
2355923560
ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base);
23561+
if (result_loc->value->type->data.pointer.is_const) {
23562+
ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant"));
23563+
return ira->codegen->invalid_inst_gen;
23564+
}
2356023565

2356123566
ZigType *container_type = result_loc->value->type->data.pointer.child_type;
23562-
2356323567
size_t elem_count = instruction->item_count;
2356423568

2356523569
if (is_slice(container_type)) {
@@ -23710,6 +23714,11 @@ static IrInstGen *ir_analyze_instruction_container_init_fields(IrAnalyze *ira,
2371023714
return result_loc;
2371123715

2371223716
ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base);
23717+
if (result_loc->value->type->data.pointer.is_const) {
23718+
ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant"));
23719+
return ira->codegen->invalid_inst_gen;
23720+
}
23721+
2371323722
ZigType *container_type = result_loc->value->type->data.pointer.child_type;
2371423723

2371523724
return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type,
@@ -27179,6 +27188,13 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
2717927188
if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
2718027189
return result_loc;
2718127190
}
27191+
27192+
ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base);
27193+
if (result_loc->value->type->data.pointer.is_const) {
27194+
ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant"));
27195+
return ira->codegen->invalid_inst_gen;
27196+
}
27197+
2718227198
IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type);
2718327199
dummy_value->value->special = ConstValSpecialRuntime;
2718427200
IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base,

test/compile_errors.zig

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,42 @@ const tests = @import("tests.zig");
22
const std = @import("std");
33

44
pub 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:15: 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:10: 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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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| {

0 commit comments

Comments
 (0)