authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-03-06 16:37:03-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-03-06 16:37:03-05:00
log07e47c058c480914d45ec0b1f9c61b76f59e6299
treeebbe6e0a1e2982de491708e3f538cad12a0eddda
parent46e258c9f76cee5b37042913c34b3a1a07cce0a6

ptrCast builtin now gives an error for removing const qualifier

closes #384

10 files changed, 34 insertions(+), 11 deletions(-)

src/analyze.cpp+13
...@@ -3753,6 +3753,19 @@ uint32_t get_ptr_align(TypeTableEntry *type) {...@@ -3753,6 +3753,19 @@ uint32_t get_ptr_align(TypeTableEntry *type) {
3753 }3753 }
3754}3754}
37553755
3756bool get_ptr_const(TypeTableEntry *type) {
3757 TypeTableEntry *ptr_type = get_codegen_ptr_type(type);
3758 if (ptr_type->id == TypeTableEntryIdPointer) {
3759 return ptr_type->data.pointer.is_const;
3760 } else if (ptr_type->id == TypeTableEntryIdFn) {
3761 return true;
3762 } else if (ptr_type->id == TypeTableEntryIdPromise) {
3763 return true;
3764 } else {
3765 zig_unreachable();
3766 }
3767}
3768
3756AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index) {3769AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index) {
3757 if (fn_entry->param_source_nodes)3770 if (fn_entry->param_source_nodes)
3758 return fn_entry->param_source_nodes[index];3771 return fn_entry->param_source_nodes[index];
src/analyze.hpp+1
...@@ -55,6 +55,7 @@ bool type_is_codegen_pointer(TypeTableEntry *type);...@@ -55,6 +55,7 @@ bool type_is_codegen_pointer(TypeTableEntry *type);
5555
56TypeTableEntry *get_codegen_ptr_type(TypeTableEntry *type);56TypeTableEntry *get_codegen_ptr_type(TypeTableEntry *type);
57uint32_t get_ptr_align(TypeTableEntry *type);57uint32_t get_ptr_align(TypeTableEntry *type);
58bool get_ptr_const(TypeTableEntry *type);
58TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);59TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);
59TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);60TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);
60bool type_is_complete(TypeTableEntry *type_entry);61bool type_is_complete(TypeTableEntry *type_entry);
src/ir.cpp+5
...@@ -16816,6 +16816,11 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc...@@ -16816,6 +16816,11 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc
16816 return ira->codegen->builtin_types.entry_invalid;16816 return ira->codegen->builtin_types.entry_invalid;
16817 }16817 }
1681816818
16819 if (get_ptr_const(src_type) && !get_ptr_const(dest_type)) {
16820 ir_add_error(ira, &instruction->base, buf_sprintf("cast discards const qualifier"));
16821 return ira->codegen->builtin_types.entry_invalid;
16822 }
16823
16819 if (instr_is_comptime(ptr)) {16824 if (instr_is_comptime(ptr)) {
16820 ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);16825 ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);
16821 if (!val)16826 if (!val)
std/buf_map.zig+1-3
...@@ -62,9 +62,7 @@ pub const BufMap = struct {...@@ -62,9 +62,7 @@ pub const BufMap = struct {
62 }62 }
6363
64 fn free(self: &BufMap, value: []const u8) void {64 fn free(self: &BufMap, value: []const u8) void {
65 // remove the const65 self.hash_map.allocator.free(value);
66 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
67 self.hash_map.allocator.free(mut_value);
68 }66 }
6967
70 fn copy(self: &BufMap, value: []const u8) ![]const u8 {68 fn copy(self: &BufMap, value: []const u8) ![]const u8 {
std/buf_set.zig+1-3
...@@ -50,9 +50,7 @@ pub const BufSet = struct {...@@ -50,9 +50,7 @@ pub const BufSet = struct {
50 }50 }
5151
52 fn free(self: &BufSet, value: []const u8) void {52 fn free(self: &BufSet, value: []const u8) void {
53 // remove the const53 self.hash_map.allocator.free(value);
54 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
55 self.hash_map.allocator.free(mut_value);
56 }54 }
5755
58 fn copy(self: &BufSet, value: []const u8) ![]const u8 {56 fn copy(self: &BufSet, value: []const u8) ![]const u8 {
std/os/index.zig+1-1
...@@ -1634,7 +1634,7 @@ pub fn argsFree(allocator: &mem.Allocator, args_alloc: []const []u8) void {...@@ -1634,7 +1634,7 @@ pub fn argsFree(allocator: &mem.Allocator, args_alloc: []const []u8) void {
1634 for (args_alloc) |arg| {1634 for (args_alloc) |arg| {
1635 total_bytes += @sizeOf([]u8) + arg.len;1635 total_bytes += @sizeOf([]u8) + arg.len;
1636 }1636 }
1637 const unaligned_allocated_buf = @ptrCast(&u8, args_alloc.ptr)[0..total_bytes];1637 const unaligned_allocated_buf = @ptrCast(&const u8, args_alloc.ptr)[0..total_bytes];
1638 const aligned_allocated_buf = @alignCast(@alignOf([]u8), unaligned_allocated_buf);1638 const aligned_allocated_buf = @alignCast(@alignOf([]u8), unaligned_allocated_buf);
1639 return allocator.free(aligned_allocated_buf);1639 return allocator.free(aligned_allocated_buf);
1640}1640}
std/special/compiler_rt/udivmod.zig+2-2
...@@ -11,8 +11,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -11,8 +11,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
11 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);11 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);
12 const Log2SingleInt = @import("../../math/index.zig").Log2Int(SingleInt);12 const Log2SingleInt = @import("../../math/index.zig").Log2Int(SingleInt);
1313
14 const n = *@ptrCast(&[2]SingleInt, &a); // TODO issue #42114 const n = *@ptrCast(&const [2]SingleInt, &a); // TODO issue #421
15 const d = *@ptrCast(&[2]SingleInt, &b); // TODO issue #42115 const d = *@ptrCast(&const [2]SingleInt, &b); // TODO issue #421
16 var q: [2]SingleInt = undefined;16 var q: [2]SingleInt = undefined;
17 var r: [2]SingleInt = undefined;17 var r: [2]SingleInt = undefined;
18 var sr: c_uint = undefined;18 var sr: c_uint = undefined;
test/cases/cast.zig+1-1
...@@ -16,7 +16,7 @@ test "integer literal to pointer cast" {...@@ -16,7 +16,7 @@ test "integer literal to pointer cast" {
16test "pointer reinterpret const float to int" {16test "pointer reinterpret const float to int" {
17 const float: f64 = 5.99999999999994648725e-01;17 const float: f64 = 5.99999999999994648725e-01;
18 const float_ptr = &float;18 const float_ptr = &float;
19 const int_ptr = @ptrCast(&i32, float_ptr);19 const int_ptr = @ptrCast(&const i32, float_ptr);
20 const int_val = *int_ptr;20 const int_val = *int_ptr;
21 assert(int_val == 858993411);21 assert(int_val == 858993411);
22}22}
test/cases/misc.zig+1-1
...@@ -261,7 +261,7 @@ test "generic malloc free" {...@@ -261,7 +261,7 @@ test "generic malloc free" {
261 const a = memAlloc(u8, 10) catch unreachable;261 const a = memAlloc(u8, 10) catch unreachable;
262 memFree(u8, a);262 memFree(u8, a);
263}263}
264const some_mem : [100]u8 = undefined;264var some_mem : [100]u8 = undefined;
265fn memAlloc(comptime T: type, n: usize) error![]T {265fn memAlloc(comptime T: type, n: usize) error![]T {
266 return @ptrCast(&T, &some_mem[0])[0..n];266 return @ptrCast(&T, &some_mem[0])[0..n];
267}267}
test/compile_errors.zig+8
...@@ -1,6 +1,14 @@...@@ -1,6 +1,14 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: &tests.CompileErrorContext) void {3pub fn addCases(cases: &tests.CompileErrorContext) void {
4 cases.add("@ptrCast discards const qualifier",
5 \\export fn entry() void {
6 \\ const x: i32 = 1234;
7 \\ const y = @ptrCast(&i32, &x);
8 \\}
9 ,
10 ".tmp_source.zig:3:15: error: cast discards const qualifier");
11
4 cases.add("comptime slice of undefined pointer non-zero len",12 cases.add("comptime slice of undefined pointer non-zero len",
5 \\export fn entry() void {13 \\export fn entry() void {
6 \\ const slice = (&i32)(undefined)[0..1];14 \\ const slice = (&i32)(undefined)[0..1];