mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
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
This commit is contained in:
parent
89812217b4
commit
55ea855e2c
3 changed files with 42 additions and 7 deletions
28
src/ir.cpp
28
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue