From e62671f643a5072fb8e56306a87a2772dc357e9c Mon Sep 17 00:00:00 2001 From: Vexu Date: Tue, 7 Apr 2020 15:12:37 +0300 Subject: [PATCH 1/2] fix missing const on address of literal --- src/all_types.hpp | 2 -- src/ir.cpp | 21 +++++++++++++-------- src/ir_print.cpp | 4 +--- test/compile_errors.zig | 28 ++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index 650dcfd0c7a8..56ce74caae98 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -3519,8 +3519,6 @@ struct IrInstSrcRef { IrInstSrc base; IrInstSrc *value; - bool is_const; - bool is_volatile; }; struct IrInstGenRef { diff --git a/src/ir.cpp b/src/ir.cpp index 5a96bc2d52ee..b57011717761 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3290,13 +3290,9 @@ static IrInstSrc *ir_build_import(IrBuilderSrc *irb, Scope *scope, AstNode *sour return &instruction->base; } -static IrInstSrc *ir_build_ref_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value, - bool is_const, bool is_volatile) -{ +static IrInstSrc *ir_build_ref_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { IrInstSrcRef *instruction = ir_build_instruction(irb, scope, source_node); instruction->value = value; - instruction->is_const = is_const; - instruction->is_volatile = is_volatile; ir_ref_instruction(value, irb->current_basic_block); @@ -5938,7 +5934,7 @@ static IrInstSrc *ir_gen_symbol(IrBuilderSrc *irb, Scope *scope, AstNode *node, } else { IrInstSrc *value = ir_build_const_type(irb, scope, node, primitive_type); if (lval == LValPtr) { - return ir_build_ref_src(irb, scope, node, value, false, false); + return ir_build_ref_src(irb, scope, node, value); } else { return ir_expr_wrap(irb, scope, value, result_loc); } @@ -7486,7 +7482,7 @@ static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value if (lval == LValPtr) { // We needed a pointer to a value, but we got a value. So we create // an instruction which just makes a pointer of it. - return ir_build_ref_src(irb, scope, value->base.source_node, value, false, false); + return ir_build_ref_src(irb, scope, value->base.source_node, value); } else if (result_loc != nullptr) { return ir_expr_wrap(irb, scope, value, result_loc); } else { @@ -23348,7 +23344,16 @@ static IrInstGen *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstSrcRef *ref_i IrInstGen *value = ref_instruction->value->child; if (type_is_invalid(value->value->type)) return ira->codegen->invalid_inst_gen; - return ir_get_ref(ira, &ref_instruction->base.base, value, ref_instruction->is_const, ref_instruction->is_volatile); + + bool is_const = false; + bool is_volatile = false; + + ZigValue *child_value = value->value; + if (child_value->special == ConstValSpecialStatic) { + is_const = true; + } + + return ir_get_ref(ira, &ref_instruction->base.base, value, is_const, is_volatile); } static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instruction, diff --git a/src/ir_print.cpp b/src/ir_print.cpp index e66b4a3cdf7b..0477f3edaa84 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1476,9 +1476,7 @@ static void ir_print_import(IrPrintSrc *irp, IrInstSrcImport *instruction) { } static void ir_print_ref(IrPrintSrc *irp, IrInstSrcRef *instruction) { - const char *const_str = instruction->is_const ? "const " : ""; - const char *volatile_str = instruction->is_volatile ? "volatile " : ""; - fprintf(irp->f, "%s%sref ", const_str, volatile_str); + fprintf(irp->f, "ref "); ir_print_other_inst_src(irp, instruction->value); } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 166ed67561c9..696ef1f6ceb8 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,34 @@ const tests = @import("tests.zig"); const std = @import("std"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.addTest("reference to const data", + \\export fn foo() void { + \\ var ptr = &[_]u8{0,0,0,0}; + \\ ptr[1] = 2; + \\} + \\export fn bar() void { + \\ var ptr = &@as(u32, 2); + \\ ptr.* = 2; + \\} + \\export fn baz() void { + \\ var ptr = &true; + \\ ptr.* = false; + \\} + \\export fn qux() void { + \\ const S = struct{ + \\ x: usize, + \\ y: usize, + \\ }; + \\ var ptr = &S{.x=1,.y=2}; + \\ ptr.x = 2; + \\} + , &[_][]const u8{ + "tmp.zig:3:14: error: cannot assign to constant", + "tmp.zig:7:13: error: cannot assign to constant", + "tmp.zig:11:13: error: cannot assign to constant", + "tmp.zig:19:13: error: cannot assign to constant", + }); + cases.addTest("cast between ?T where T is not a pointer", \\pub const fnty1 = ?fn (i8) void; \\pub const fnty2 = ?fn (u64) void; From 95fefcd4c91e517a51f4b55924979421c6f7e8d3 Mon Sep 17 00:00:00 2001 From: Vexu Date: Tue, 7 Apr 2020 15:24:49 +0300 Subject: [PATCH 2/2] fix broken tests --- lib/std/json.zig | 11 ++++++----- lib/std/testing.zig | 3 ++- test/compile_errors.zig | 10 +++++----- test/stage1/behavior/for.zig | 4 ++-- test/stage1/behavior/pointers.zig | 6 +++--- test/stage1/behavior/slice.zig | 4 ++-- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/lib/std/json.zig b/lib/std/json.zig index 79830d8a2c45..d271b6c19fd5 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -1327,12 +1327,13 @@ test "Value.jsonStringify" { { var buffer: [10]u8 = undefined; var fbs = std.io.fixedBufferStream(&buffer); + var vals = [_]Value{ + .{ .Integer = 1 }, + .{ .Integer = 2 }, + .{ .Integer = 3 }, + }; try (Value{ - .Array = Array.fromOwnedSlice(undefined, &[_]Value{ - .{ .Integer = 1 }, - .{ .Integer = 2 }, - .{ .Integer = 3 }, - }), + .Array = Array.fromOwnedSlice(undefined, &vals), }).jsonStringify(.{}, fbs.outStream()); testing.expectEqualSlices(u8, fbs.getWritten(), "[1,2,3]"); } diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 4f527ba700ab..4b629156f6e2 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -7,7 +7,8 @@ pub const FailingAllocator = @import("testing/failing_allocator.zig").FailingAll pub const allocator = &allocator_instance.allocator; pub var allocator_instance = LeakCountAllocator.init(&base_allocator_instance.allocator); -pub const failing_allocator = &FailingAllocator.init(&base_allocator_instance.allocator, 0).allocator; +pub const failing_allocator = &failing_allocator_instance.allocator; +pub var failing_allocator_instance = FailingAllocator.init(&base_allocator_instance.allocator, 0); pub var base_allocator_instance = std.heap.ThreadSafeFixedBufferAllocator.init(allocator_mem[0..]); var allocator_mem: [1024 * 1024]u8 = undefined; diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 696ef1f6ceb8..1d8f5e17f98e 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -997,7 +997,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ const x = 1 << &@as(u8, 10); \\} , &[_][]const u8{ - "tmp.zig:2:21: error: shift amount has to be an integer type, but found '*u8'", + "tmp.zig:2:21: error: shift amount has to be an integer type, but found '*const u8'", "tmp.zig:2:17: note: referenced here", }); @@ -1006,7 +1006,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ const x = &@as(u8, 1) << 10; \\} , &[_][]const u8{ - "tmp.zig:2:16: error: bit shifting operation expected integer type, found '*u8'", + "tmp.zig:2:16: error: bit shifting operation expected integer type, found '*const u8'", "tmp.zig:2:27: note: referenced here", }); @@ -6033,7 +6033,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ fn bar(self: *const Foo) void {} \\}; , &[_][]const u8{ - "tmp.zig:2:4: error: variable of type '*comptime_int' must be const or comptime", + "tmp.zig:2:4: error: variable of type '*const comptime_int' must be const or comptime", "tmp.zig:5:4: error: variable of type '(undefined)' must be const or comptime", "tmp.zig:8:4: error: variable of type 'comptime_int' must be const or comptime", "tmp.zig:11:4: error: variable of type 'comptime_float' must be const or comptime", @@ -6877,12 +6877,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ const word: u16 = @bitCast(u16, bytes[0..]); \\} \\export fn foo2() void { - \\ var bytes: []u8 = &[_]u8{1, 2}; + \\ var bytes: []const u8 = &[_]u8{1, 2}; \\ const word: u16 = @bitCast(u16, bytes); \\} , &[_][]const u8{ "tmp.zig:3:42: error: unable to @bitCast from pointer type '*[2]u8'", - "tmp.zig:7:32: error: destination type 'u16' has size 2 but source type '[]u8' has size 16", + "tmp.zig:7:32: error: destination type 'u16' has size 2 but source type '[]const u8' has size 16", "tmp.zig:7:37: note: referenced here", }); diff --git a/test/stage1/behavior/for.zig b/test/stage1/behavior/for.zig index c0b1cf264afa..fd98ec48dee5 100644 --- a/test/stage1/behavior/for.zig +++ b/test/stage1/behavior/for.zig @@ -161,8 +161,8 @@ test "for copies its payload" { test "for on slice with allowzero ptr" { const S = struct { - fn doTheTest(slice: []u8) void { - var ptr = @ptrCast([*]allowzero u8, slice.ptr)[0..slice.len]; + fn doTheTest(slice: []const u8) void { + var ptr = @ptrCast([*]const allowzero u8, slice.ptr)[0..slice.len]; for (ptr) |x, i| expect(x == i + 1); for (ptr) |*x, i| expect(x.* == i + 1); } diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig index 6b86c2f6ac84..fa5f2a469db1 100644 --- a/test/stage1/behavior/pointers.zig +++ b/test/stage1/behavior/pointers.zig @@ -253,7 +253,7 @@ test "pointer sentinel with enums" { }; fn doTheTest() void { - var ptr: [*:.sentinel]Number = &[_:.sentinel]Number{ .one, .two, .two, .one }; + var ptr: [*:.sentinel]const Number = &[_:.sentinel]Number{ .one, .two, .two, .one }; expect(ptr[4] == .sentinel); // TODO this should be comptime expect, see #3731 } }; @@ -264,7 +264,7 @@ test "pointer sentinel with enums" { test "pointer sentinel with optional element" { const S = struct { fn doTheTest() void { - var ptr: [*:null]?i32 = &[_:null]?i32{ 1, 2, 3, 4 }; + var ptr: [*:null]const ?i32 = &[_:null]?i32{ 1, 2, 3, 4 }; expect(ptr[4] == null); // TODO this should be comptime expect, see #3731 } }; @@ -276,7 +276,7 @@ test "pointer sentinel with +inf" { const S = struct { fn doTheTest() void { const inf = std.math.inf_f32; - var ptr: [*:inf]f32 = &[_:inf]f32{ 1.1, 2.2, 3.3, 4.4 }; + var ptr: [*:inf]const f32 = &[_:inf]f32{ 1.1, 2.2, 3.3, 4.4 }; expect(ptr[4] == inf); // TODO this should be comptime expect, see #3731 } }; diff --git a/test/stage1/behavior/slice.zig b/test/stage1/behavior/slice.zig index e357ad2f0f30..1faefe680037 100644 --- a/test/stage1/behavior/slice.zig +++ b/test/stage1/behavior/slice.zig @@ -218,9 +218,9 @@ test "slice syntax resulting in pointer-to-array" { } fn testPointer0() void { - var pointer: [*]u0 = &[1]u0{0}; + var pointer: [*]const u0 = &[1]u0{0}; var slice = pointer[0..1]; - comptime expect(@TypeOf(slice) == *[1]u0); + comptime expect(@TypeOf(slice) == *const [1]u0); expect(slice[0] == 0); }