aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-12-26 15:45:50 -0500
committerAndrew Kelley <superjoe30@gmail.com>2016-12-26 15:45:50 -0500
commit735cdbfdaca6405d1465ea859032412499c658d8 (patch)
treea3b6655d26985adafbf71903c5d5bb7049a45454 /src/ir.cpp
parentaee7ad3de2e3c334ec5aac2d355e4eed086f1cdf (diff)
downloadzig-735cdbfdaca6405d1465ea859032412499c658d8.tar.gz
zig-735cdbfdaca6405d1465ea859032412499c658d8.zip
IR: pass intToPtrCast test
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp88
1 files changed, 84 insertions, 4 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 51a652451b..7eac05def6 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -52,6 +52,7 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ
ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) {
assert(const_val->special == ConstValSpecialStatic);
+ assert(const_val->data.x_ptr.special != ConstPtrSpecialRuntime);
ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr;
size_t index = const_val->data.x_ptr.index;
@@ -459,6 +460,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *
return IrInstructionIdWidenOrShorten;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrToInt *) {
+ return IrInstructionIdPtrToInt;
+}
+
+static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToPtr *) {
+ return IrInstructionIdIntToPtr;
+}
+
template<typename T>
static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) {
T *special_instruction = allocate<T>(1);
@@ -1899,6 +1908,30 @@ static IrInstruction *ir_build_widen_or_shorten(IrBuilder *irb, Scope *scope, As
return &instruction->base;
}
+static IrInstruction *ir_build_int_to_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *target)
+{
+ IrInstructionIntToPtr *instruction = ir_build_instruction<IrInstructionIntToPtr>(
+ irb, scope, source_node);
+ instruction->target = target;
+
+ ir_ref_instruction(target);
+
+ return &instruction->base;
+}
+
+static IrInstruction *ir_build_ptr_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *target)
+{
+ IrInstructionPtrToInt *instruction = ir_build_instruction<IrInstructionPtrToInt>(
+ irb, scope, source_node);
+ instruction->target = target;
+
+ ir_ref_instruction(target);
+
+ return &instruction->base;
+}
+
static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
results[ReturnKindUnconditional] = 0;
results[ReturnKindError] = 0;
@@ -4657,8 +4690,6 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
*const_val = *other_val;
const_val->type = new_type;
break;
- case CastOpPtrToInt:
- case CastOpIntToPtr:
case CastOpResizeSlice:
case CastOpBytesToSlice:
// can't do it
@@ -5234,6 +5265,51 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction
return result;
}
+static IrInstruction *ir_analyze_ptr_to_int(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *target, TypeTableEntry *wanted_type)
+{
+ assert(wanted_type->id == TypeTableEntryIdInt);
+
+ if (instr_is_comptime(target)) {
+ ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
+ if (!val)
+ return ira->codegen->invalid_instruction;
+ if (val->data.x_ptr.special == ConstPtrSpecialRuntime) {
+ IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, wanted_type, val->depends_on_compile_var);
+ bignum_init_unsigned(&result->value.data.x_bignum, val->data.x_ptr.index);
+ return result;
+ }
+ }
+
+ IrInstruction *result = ir_build_ptr_to_int(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, target);
+ result->value.type = wanted_type;
+ return result;
+}
+
+static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *target, TypeTableEntry *wanted_type)
+{
+ assert(wanted_type->id == TypeTableEntryIdPointer);
+
+ if (instr_is_comptime(target)) {
+ ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
+ if (!val)
+ return ira->codegen->invalid_instruction;
+ IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, wanted_type, val->depends_on_compile_var);
+ result->value.data.x_ptr.base_ptr = nullptr;
+ result->value.data.x_ptr.index = bignum_to_twos_complement(&val->data.x_bignum);
+ result->value.data.x_ptr.special = ConstPtrSpecialRuntime;
+ return result;
+ }
+
+ IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, target);
+ result->value.type = wanted_type;
+ return result;
+}
static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
TypeTableEntry *wanted_type, IrInstruction *value)
@@ -5270,7 +5346,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
if ((wanted_type_canon == isize_type || wanted_type_canon == usize_type) &&
type_is_codegen_pointer(actual_type_canon))
{
- return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpPtrToInt, false);
+ return ir_analyze_ptr_to_int(ira, source_instr, value, wanted_type);
}
@@ -5278,7 +5354,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
if (wanted_type_canon->id == TypeTableEntryIdPointer &&
(actual_type_canon == isize_type || actual_type_canon == usize_type))
{
- return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpIntToPtr, false);
+ return ir_analyze_int_to_ptr(ira, source_instr, value, wanted_type);
}
// explicit widening or shortening cast
@@ -9937,6 +10013,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
case IrInstructionIdInvalid:
case IrInstructionIdPointerReinterpret:
case IrInstructionIdWidenOrShorten:
+ case IrInstructionIdIntToPtr:
+ case IrInstructionIdPtrToInt:
case IrInstructionIdStructInit:
case IrInstructionIdStructFieldPtr:
case IrInstructionIdEnumFieldPtr:
@@ -10244,6 +10322,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdInitEnum:
case IrInstructionIdPointerReinterpret:
case IrInstructionIdWidenOrShorten:
+ case IrInstructionIdPtrToInt:
+ case IrInstructionIdIntToPtr:
return false;
case IrInstructionIdAsm:
{