authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-16 12:03:37-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-16 12:08:14-05:00
log757d0665ae951bdd5cb754adbe433488f0bea8c4
treee13169d39715db750f8d49f9c6b7dd386d415fcd
parent7533d1b14cb105f604cac3bd1e9dd99cab7a0c2b
signaturelock-open Commit is signed but in an unrecognized format.

implement comptime pointer cast

closes #955 closes #1835

2 files changed, 31 insertions(+), 3 deletions(-)

src/ir.cpp+22-3
......@@ -166,6 +166,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node,
166166static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr,
167167 ZigType *dest_type, IrInstruction *dest_type_src);
168168static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed);
169static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs);
169170
170171static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
171172 assert(get_src_ptr_type(const_val->type) != nullptr);
......@@ -7364,15 +7365,31 @@ static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction,
73647365 return ir_add_error_node(ira, source_instruction->source_node, msg);
73657366}
73667367
7368// This function takes a comptime ptr and makes the child const value conform to the type
7369// described by the pointer.
7370static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, AstNode *source_node, ConstExprValue *ptr_val) {
7371 Error err;
7372 assert(ptr_val->type->id == ZigTypeIdPointer);
7373 ConstExprValue tmp = {};
7374 tmp.special = ConstValSpecialStatic;
7375 tmp.type = ptr_val->type->data.pointer.child_type;
7376 if ((err = ir_read_const_ptr(ira, source_node, &tmp, ptr_val)))
7377 return err;
7378 ConstExprValue *child_val = const_ptr_pointee_unchecked(ira->codegen, ptr_val);
7379 copy_const_val(child_val, &tmp, false);
7380 return ErrorNone;
7381}
7382
73677383static ConstExprValue *ir_const_ptr_pointee(IrAnalyze *ira, ConstExprValue *const_val, AstNode *source_node) {
7384 Error err;
73687385 ConstExprValue *val = const_ptr_pointee_unchecked(ira->codegen, const_val);
73697386 assert(val != nullptr);
73707387 assert(const_val->type->id == ZigTypeIdPointer);
73717388 ZigType *expected_type = const_val->type->data.pointer.child_type;
73727389 if (!types_have_same_zig_comptime_repr(val->type, expected_type)) {
7373 ir_add_error_node(ira, source_node,
7374 buf_sprintf("TODO handle comptime reinterpreted pointer. See https://github.com/ziglang/zig/issues/955"));
7375 return nullptr;
7390 if ((err = eval_comptime_ptr_reinterpret(ira, source_node, const_val)))
7391 return nullptr;
7392 return const_ptr_pointee_unchecked(ira->codegen, const_val);
73767393 }
73777394 return val;
73787395}
......@@ -19990,6 +20007,8 @@ static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruct
1999020007}
1999120008
1999220009static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) {
20010 if (val->special == ConstValSpecialUndef)
20011 val->special = ConstValSpecialStatic;
1999320012 assert(val->special == ConstValSpecialStatic);
1999420013 switch (val->type->id) {
1999520014 case ZigTypeIdInvalid:
std/mem.zig+9
......@@ -510,6 +510,15 @@ pub fn readIntSlice(comptime T: type, bytes: []const u8, endian: builtin.Endian)
510510 return readInt(T, @ptrCast(*const [@sizeOf(T)]u8, bytes.ptr), endian);
511511}
512512
513test "comptime read/write int" {
514 comptime {
515 var bytes: [2]u8 = undefined;
516 std.mem.writeIntLittle(u16, &bytes, 0x1234);
517 const result = std.mem.readIntBig(u16, &bytes);
518 std.debug.assert(result == 0x3412);
519 }
520}
521
513522test "readIntBig and readIntLittle" {
514523 assert(readIntSliceBig(u0, []u8{}) == 0x0);
515524 assert(readIntSliceLittle(u0, []u8{}) == 0x0);