Merge pull request #4971 from Vexu/const-ref

Fix missing const on address of literal
This commit is contained in:
Andrew Kelley 2020-04-07 14:24:50 -04:00 committed by GitHub
commit 87a7ea4c42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 62 additions and 31 deletions

View File

@ -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]");
}

View File

@ -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;

View File

@ -3519,8 +3519,6 @@ struct IrInstSrcRef {
IrInstSrc base;
IrInstSrc *value;
bool is_const;
bool is_volatile;
};
struct IrInstGenRef {

View File

@ -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<IrInstSrcRef>(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,

View File

@ -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);
}

View File

@ -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;
@ -969,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",
});
@ -978,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",
});
@ -6005,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",
@ -6849,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",
});

View File

@ -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);
}

View File

@ -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
}
};

View File

@ -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);
}