diff --git a/src/all_types.hpp b/src/all_types.hpp index 36f557a946039110b96eb50baa55a4d47f7dac9e..25fb6ecf2134df7bcf9c850cc163ae8f0de1785a 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 79a332396693c572267c0029f23cc4d934bc6eb6..281dfc7ef91c861369df2ec4ce3b2afb8da5a101 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 e99baf66ff69a11440c5a2b42ad8cb5280e50968..89abae8cec055d910a9c38aba78288a797aaf484 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 ed833b285812110cbd117aaba61609ce29b50a5b..4e9da801bf25b4a4a7d25b2c869aea63a67c76a2 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"); }