aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2018-12-16 12:03:37 -0500
committerAndrew Kelley <andrew@ziglang.org>2018-12-16 12:08:14 -0500
commit757d0665ae951bdd5cb754adbe433488f0bea8c4 (patch)
treee13169d39715db750f8d49f9c6b7dd386d415fcd /src
parent7533d1b14cb105f604cac3bd1e9dd99cab7a0c2b (diff)
downloadzig-757d0665ae951bdd5cb754adbe433488f0bea8c4.tar.gz
zig-757d0665ae951bdd5cb754adbe433488f0bea8c4.zip
implement comptime pointer cast
closes #955 closes #1835
Diffstat (limited to 'src')
-rw-r--r--src/ir.cpp25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index dc87f040bc..ef7ad221cf 100644
--- a/src/ir.cpp
+++ b/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,
ZigType *dest_type, IrInstruction *dest_type_src);
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) {
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);
}
+// 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) {
+ Error err;
ConstExprValue *val = const_ptr_pointee_unchecked(ira->codegen, const_val);
assert(val != nullptr);
assert(const_val->type->id == ZigTypeIdPointer);
ZigType *expected_type = const_val->type->data.pointer.child_type;
if (!types_have_same_zig_comptime_repr(val->type, expected_type)) {
- ir_add_error_node(ira, source_node,
- buf_sprintf("TODO handle comptime reinterpreted pointer. See https://github.com/ziglang/zig/issues/955"));
- return nullptr;
+ if ((err = eval_comptime_ptr_reinterpret(ira, source_node, const_val)))
+ return nullptr;
+ return const_ptr_pointee_unchecked(ira->codegen, const_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) {
+ if (val->special == ConstValSpecialUndef)
+ val->special = ConstValSpecialStatic;
assert(val->special == ConstValSpecialStatic);
switch (val->type->id) {
case ZigTypeIdInvalid: