mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 22:04:21 +00:00
parent
7533d1b14c
commit
757d0665ae
2 changed files with 31 additions and 3 deletions
23
src/ir.cpp
23
src/ir.cpp
|
|
@ -166,6 +166,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node,
|
||||||
static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr,
|
static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr,
|
||||||
ZigType *dest_type, IrInstruction *dest_type_src);
|
ZigType *dest_type, IrInstruction *dest_type_src);
|
||||||
static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed);
|
static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed);
|
||||||
|
static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs);
|
||||||
|
|
||||||
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
|
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
|
||||||
assert(get_src_ptr_type(const_val->type) != nullptr);
|
assert(get_src_ptr_type(const_val->type) != nullptr);
|
||||||
|
|
@ -7364,15 +7365,31 @@ static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction,
|
||||||
return ir_add_error_node(ira, source_instruction->source_node, msg);
|
return ir_add_error_node(ira, source_instruction->source_node, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function takes a comptime ptr and makes the child const value conform to the type
|
||||||
|
// described by the pointer.
|
||||||
|
static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, AstNode *source_node, ConstExprValue *ptr_val) {
|
||||||
|
Error err;
|
||||||
|
assert(ptr_val->type->id == ZigTypeIdPointer);
|
||||||
|
ConstExprValue tmp = {};
|
||||||
|
tmp.special = ConstValSpecialStatic;
|
||||||
|
tmp.type = ptr_val->type->data.pointer.child_type;
|
||||||
|
if ((err = ir_read_const_ptr(ira, source_node, &tmp, ptr_val)))
|
||||||
|
return err;
|
||||||
|
ConstExprValue *child_val = const_ptr_pointee_unchecked(ira->codegen, ptr_val);
|
||||||
|
copy_const_val(child_val, &tmp, false);
|
||||||
|
return ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
static ConstExprValue *ir_const_ptr_pointee(IrAnalyze *ira, ConstExprValue *const_val, AstNode *source_node) {
|
static ConstExprValue *ir_const_ptr_pointee(IrAnalyze *ira, ConstExprValue *const_val, AstNode *source_node) {
|
||||||
|
Error err;
|
||||||
ConstExprValue *val = const_ptr_pointee_unchecked(ira->codegen, const_val);
|
ConstExprValue *val = const_ptr_pointee_unchecked(ira->codegen, const_val);
|
||||||
assert(val != nullptr);
|
assert(val != nullptr);
|
||||||
assert(const_val->type->id == ZigTypeIdPointer);
|
assert(const_val->type->id == ZigTypeIdPointer);
|
||||||
ZigType *expected_type = const_val->type->data.pointer.child_type;
|
ZigType *expected_type = const_val->type->data.pointer.child_type;
|
||||||
if (!types_have_same_zig_comptime_repr(val->type, expected_type)) {
|
if (!types_have_same_zig_comptime_repr(val->type, expected_type)) {
|
||||||
ir_add_error_node(ira, source_node,
|
if ((err = eval_comptime_ptr_reinterpret(ira, source_node, const_val)))
|
||||||
buf_sprintf("TODO handle comptime reinterpreted pointer. See https://github.com/ziglang/zig/issues/955"));
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
return const_ptr_pointee_unchecked(ira->codegen, const_val);
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
@ -19990,6 +20007,8 @@ static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruct
|
||||||
}
|
}
|
||||||
|
|
||||||
static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) {
|
static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) {
|
||||||
|
if (val->special == ConstValSpecialUndef)
|
||||||
|
val->special = ConstValSpecialStatic;
|
||||||
assert(val->special == ConstValSpecialStatic);
|
assert(val->special == ConstValSpecialStatic);
|
||||||
switch (val->type->id) {
|
switch (val->type->id) {
|
||||||
case ZigTypeIdInvalid:
|
case ZigTypeIdInvalid:
|
||||||
|
|
|
||||||
|
|
@ -510,6 +510,15 @@ pub fn readIntSlice(comptime T: type, bytes: []const u8, endian: builtin.Endian)
|
||||||
return readInt(T, @ptrCast(*const [@sizeOf(T)]u8, bytes.ptr), endian);
|
return readInt(T, @ptrCast(*const [@sizeOf(T)]u8, bytes.ptr), endian);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "comptime read/write int" {
|
||||||
|
comptime {
|
||||||
|
var bytes: [2]u8 = undefined;
|
||||||
|
std.mem.writeIntLittle(u16, &bytes, 0x1234);
|
||||||
|
const result = std.mem.readIntBig(u16, &bytes);
|
||||||
|
std.debug.assert(result == 0x3412);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test "readIntBig and readIntLittle" {
|
test "readIntBig and readIntLittle" {
|
||||||
assert(readIntSliceBig(u0, []u8{}) == 0x0);
|
assert(readIntSliceBig(u0, []u8{}) == 0x0);
|
||||||
assert(readIntSliceLittle(u0, []u8{}) == 0x0);
|
assert(readIntSliceLittle(u0, []u8{}) == 0x0);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue