Commit 261517aa44

Andrew Kelley <superjoe30@gmail.com>
2016-01-27 20:43:03
add explicit cast from isize/usize to pointer
closes #91
1 parent e809baa
src/all_types.hpp
@@ -325,6 +325,7 @@ enum CastOp {
     CastOpNoCast, // signifies the function call expression is not a cast
     CastOpNoop, // fn call expr is a cast, but does nothing
     CastOpPtrToInt,
+    CastOpIntToPtr,
     CastOpIntWidenOrShorten,
     CastOpToUnknownSizeArray,
     CastOpMaybeWrap,
src/analyze.cpp
@@ -3058,11 +3058,14 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex
         case CastOpNoCast:
             zig_unreachable();
         case CastOpNoop:
-        case CastOpPtrToInt:
         case CastOpIntWidenOrShorten:
         case CastOpPointerReinterpret:
             *const_val = *other_val;
             break;
+        case CastOpPtrToInt:
+        case CastOpIntToPtr:
+            // can't do it
+            break;
         case CastOpToUnknownSizeArray:
             {
                 TypeTableEntry *other_type = get_resolved_expr(expr_node)->type_entry;
@@ -3148,6 +3151,16 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
         return wanted_type;
     }
 
+
+    // explicit cast from isize or usize to pointer
+    if (wanted_type->id == TypeTableEntryIdPointer &&
+        (actual_type == g->builtin_types.entry_isize || actual_type == g->builtin_types.entry_usize))
+    {
+        node->data.fn_call_expr.cast_op = CastOpIntToPtr;
+        eval_const_expr_implicit_cast(g, node, expr_node);
+        return wanted_type;
+    }
+
     // explicit cast from any int to any other int
     if (wanted_type->id == TypeTableEntryIdInt &&
         actual_type->id == TypeTableEntryIdInt)
src/codegen.cpp
@@ -428,6 +428,9 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
         case CastOpPtrToInt:
             add_debug_source_node(g, node);
             return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
+        case CastOpIntToPtr:
+            add_debug_source_node(g, node);
+            return LLVMBuildIntToPtr(g->builder, expr_val, wanted_type->type_ref, "");
         case CastOpPointerReinterpret:
             add_debug_source_node(g, node);
             return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");
test/run_tests.cpp
@@ -1303,6 +1303,19 @@ pub fn main(args: [][]u8) -> %void {
         %%stdout.printf("BAD\n");
     }
     %%stdout.printf("OK\n");
+}
+    )SOURCE", "OK\n");
+
+    add_simple_case("int to ptr cast", R"SOURCE(
+import "std.zig";
+pub fn main(args: [][]u8) -> %void {
+    const x = isize(13);
+    const y = (&u8)(x);
+    const z = usize(y);
+    if (z != 13) {
+        %%stdout.printf("BAD\n");
+    }
+    %%stdout.printf("OK\n");
 }
     )SOURCE", "OK\n");
 }