diff --git a/src/all_types.hpp b/src/all_types.hpp index 36f557a94..25fb6ecf2 100644 --- a/src/all_types.hpp +++ b/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, diff --git a/src/analyze.cpp b/src/analyze.cpp index 79a332396..281dfc7ef 100644 --- a/src/analyze.cpp +++ b/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) diff --git a/src/codegen.cpp b/src/codegen.cpp index e99baf66f..89abae8ce 100644 --- a/src/codegen.cpp +++ b/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, ""); diff --git a/test/run_tests.cpp b/test/run_tests.cpp index ed833b285..4e9da801b 100644 --- a/test/run_tests.cpp +++ b/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"); }