authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-25 13:10:29+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-25 17:38:56-05:00
log55ea855e2cefe8dcdb5fab9be66aa6ca3acd0370
tree8b08c867108b6e589ea5e6504728199a4482fbd5
parent89812217b4e5fee7e2851266c17c9d47204a1573

ir: Various fixes for comptime ptr handling

* Correctly fold ptrToInt on optional types * Generate null as ConstPtrSpecialNull in intToPtr * Correctly stop ptrToInt on ?*T where T is zero-sized Closes #4535

3 files changed, 42 insertions(+), 7 deletions(-)

src/ir.cpp+21-7
......@@ -27851,9 +27851,15 @@ static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, Ir
2785127851 }
2785227852
2785327853 IrInstGen *result = ir_const(ira, source_instr, ptr_type);
27854 result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
27855 result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar;
27856 result->value->data.x_ptr.data.hard_coded_addr.addr = addr;
27854 if (ptr_type->id == ZigTypeIdOptional && addr == 0) {
27855 result->value->data.x_ptr.special = ConstPtrSpecialNull;
27856 result->value->data.x_ptr.mut = ConstPtrMutComptimeConst;
27857 } else {
27858 result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
27859 result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar;
27860 result->value->data.x_ptr.data.hard_coded_addr.addr = addr;
27861 }
27862
2785727863 return result;
2785827864 }
2785927865
......@@ -27911,15 +27917,15 @@ static IrInstGen *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstSrcPtr
2791127917
2791227918 ZigType *usize = ira->codegen->builtin_types.entry_usize;
2791327919
27914 // We check size explicitly so we can use get_src_ptr_type here.
27915 if (get_src_ptr_type(target->value->type) == nullptr) {
27920 ZigType *src_ptr_type = get_src_ptr_type(target->value->type);
27921 if (src_ptr_type == nullptr) {
2791627922 ir_add_error(ira, &target->base,
2791727923 buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value->type->name)));
2791827924 return ira->codegen->invalid_inst_gen;
2791927925 }
2792027926
2792127927 bool has_bits;
27922 if ((err = type_has_bits2(ira->codegen, target->value->type, &has_bits)))
27928 if ((err = type_has_bits2(ira->codegen, src_ptr_type, &has_bits)))
2792327929 return ira->codegen->invalid_inst_gen;
2792427930
2792527931 if (!has_bits) {
......@@ -27932,11 +27938,19 @@ static IrInstGen *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstSrcPtr
2793227938 ZigValue *val = ir_resolve_const(ira, target, UndefBad);
2793327939 if (!val)
2793427940 return ira->codegen->invalid_inst_gen;
27935 if (val->type->id == ZigTypeIdPointer && val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
27941
27942 // Since we've already run this type trough get_codegen_ptr_type it is
27943 // safe to access the x_ptr fields
27944 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
2793627945 IrInstGen *result = ir_const(ira, &instruction->base.base, usize);
2793727946 bigint_init_unsigned(&result->value->data.x_bigint, val->data.x_ptr.data.hard_coded_addr.addr);
2793827947 result->value->type = usize;
2793927948 return result;
27949 } else if (val->data.x_ptr.special == ConstPtrSpecialNull) {
27950 IrInstGen *result = ir_const(ira, &instruction->base.base, usize);
27951 bigint_init_unsigned(&result->value->data.x_bigint, 0);
27952 result->value->type = usize;
27953 return result;
2794027954 }
2794127955 }
2794227956
test/compile_errors.zig+9
......@@ -3,6 +3,15 @@ const builtin = @import("builtin");
33const Target = @import("std").Target;
44
55pub fn addCases(cases: *tests.CompileErrorContext) void {
6 cases.addTest("@ptrToInt with pointer to zero-sized type",
7 \\export fn entry() void {
8 \\ var pointer: ?*u0 = null;
9 \\ var x = @ptrToInt(pointer);
10 \\}
11 , &[_][]const u8{
12 "tmp.zig:3:23: error: pointer to size 0 type has no address",
13 });
14
615 cases.addTest("slice to pointer conversion mismatch",
716 \\pub fn bytesAsSlice(bytes: var) [*]align(1) const u16 {
817 \\ return @ptrCast([*]align(1) const u16, bytes.ptr)[0..1];
test/stage1/behavior/pointers.zig+12
......@@ -318,3 +318,15 @@ test "pointer arithmetic affects the alignment" {
318318 expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 4);
319319 }
320320}
321
322test "@ptrToInt on null optional at comptime" {
323 {
324 const pointer = @intToPtr(?*u8, 0x000);
325 const x = @ptrToInt(pointer);
326 comptime expect(0 == @ptrToInt(pointer));
327 }
328 {
329 const pointer = @intToPtr(?*u8, 0xf00);
330 comptime expect(0xf00 == @ptrToInt(pointer));
331 }
332}