Commit 55ea855e2c
Changed files (3)
src
test
stage1
behavior
src/ir.cpp
@@ -27851,9 +27851,15 @@ static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, Ir
}
IrInstGen *result = ir_const(ira, source_instr, ptr_type);
- result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
- result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar;
- result->value->data.x_ptr.data.hard_coded_addr.addr = addr;
+ if (ptr_type->id == ZigTypeIdOptional && addr == 0) {
+ result->value->data.x_ptr.special = ConstPtrSpecialNull;
+ result->value->data.x_ptr.mut = ConstPtrMutComptimeConst;
+ } else {
+ result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
+ result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar;
+ result->value->data.x_ptr.data.hard_coded_addr.addr = addr;
+ }
+
return result;
}
@@ -27911,15 +27917,15 @@ static IrInstGen *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstSrcPtr
ZigType *usize = ira->codegen->builtin_types.entry_usize;
- // We check size explicitly so we can use get_src_ptr_type here.
- if (get_src_ptr_type(target->value->type) == nullptr) {
+ ZigType *src_ptr_type = get_src_ptr_type(target->value->type);
+ if (src_ptr_type == nullptr) {
ir_add_error(ira, &target->base,
buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value->type->name)));
return ira->codegen->invalid_inst_gen;
}
bool has_bits;
- if ((err = type_has_bits2(ira->codegen, target->value->type, &has_bits)))
+ if ((err = type_has_bits2(ira->codegen, src_ptr_type, &has_bits)))
return ira->codegen->invalid_inst_gen;
if (!has_bits) {
@@ -27932,11 +27938,19 @@ static IrInstGen *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstSrcPtr
ZigValue *val = ir_resolve_const(ira, target, UndefBad);
if (!val)
return ira->codegen->invalid_inst_gen;
- if (val->type->id == ZigTypeIdPointer && val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
+
+ // Since we've already run this type trough get_codegen_ptr_type it is
+ // safe to access the x_ptr fields
+ if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
IrInstGen *result = ir_const(ira, &instruction->base.base, usize);
bigint_init_unsigned(&result->value->data.x_bigint, val->data.x_ptr.data.hard_coded_addr.addr);
result->value->type = usize;
return result;
+ } else if (val->data.x_ptr.special == ConstPtrSpecialNull) {
+ IrInstGen *result = ir_const(ira, &instruction->base.base, usize);
+ bigint_init_unsigned(&result->value->data.x_bigint, 0);
+ result->value->type = usize;
+ return result;
}
}
test/stage1/behavior/pointers.zig
@@ -318,3 +318,15 @@ test "pointer arithmetic affects the alignment" {
expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 4);
}
}
+
+test "@ptrToInt on null optional at comptime" {
+ {
+ const pointer = @intToPtr(?*u8, 0x000);
+ const x = @ptrToInt(pointer);
+ comptime expect(0 == @ptrToInt(pointer));
+ }
+ {
+ const pointer = @intToPtr(?*u8, 0xf00);
+ comptime expect(0xf00 == @ptrToInt(pointer));
+ }
+}
test/compile_errors.zig
@@ -3,6 +3,15 @@ const builtin = @import("builtin");
const Target = @import("std").Target;
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest("@ptrToInt with pointer to zero-sized type",
+ \\export fn entry() void {
+ \\ var pointer: ?*u0 = null;
+ \\ var x = @ptrToInt(pointer);
+ \\}
+ , &[_][]const u8{
+ "tmp.zig:3:23: error: pointer to size 0 type has no address",
+ });
+
cases.addTest("slice to pointer conversion mismatch",
\\pub fn bytesAsSlice(bytes: var) [*]align(1) const u16 {
\\ return @ptrCast([*]align(1) const u16, bytes.ptr)[0..1];