Skip to content

Fix missing compile error on assign to slice and array parameters #4975

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
18 changes: 17 additions & 1 deletion src/ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -27175,6 +27184,13 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
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,
Expand Down
36 changes: 36 additions & 0 deletions test/compile_errors.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
2 changes: 1 addition & 1 deletion test/tests.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand Down