| author | |
| committer | |
| log | 261517aa4443404e0ab7b7925937a5c1046f58f5 |
| tree | f8668a9360dc75cefbe3492f8e0b8244d95be7dc |
| parent | e809baa8662ed2a8ad0d2b304bc89c4a6982f3dd |
closes #914 files changed, 31 insertions(+), 1 deletions(-)
src/all_types.hpp+1| ... | @@ -325,6 +325,7 @@ enum CastOp { | ... | @@ -325,6 +325,7 @@ enum CastOp { |
| 325 | CastOpNoCast, // signifies the function call expression is not a cast | 325 | CastOpNoCast, // signifies the function call expression is not a cast |
| 326 | CastOpNoop, // fn call expr is a cast, but does nothing | 326 | CastOpNoop, // fn call expr is a cast, but does nothing |
| 327 | CastOpPtrToInt, | 327 | CastOpPtrToInt, |
| 328 | CastOpIntToPtr, | ||
| 328 | CastOpIntWidenOrShorten, | 329 | CastOpIntWidenOrShorten, |
| 329 | CastOpToUnknownSizeArray, | 330 | CastOpToUnknownSizeArray, |
| 330 | CastOpMaybeWrap, | 331 | CastOpMaybeWrap, |
src/analyze.cpp+14-1| ... | @@ -3058,11 +3058,14 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex | ... | @@ -3058,11 +3058,14 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex |
| 3058 | case CastOpNoCast: | 3058 | case CastOpNoCast: |
| 3059 | zig_unreachable(); | 3059 | zig_unreachable(); |
| 3060 | case CastOpNoop: | 3060 | case CastOpNoop: |
| 3061 | case CastOpPtrToInt: | ||
| 3062 | case CastOpIntWidenOrShorten: | 3061 | case CastOpIntWidenOrShorten: |
| 3063 | case CastOpPointerReinterpret: | 3062 | case CastOpPointerReinterpret: |
| 3064 | *const_val = *other_val; | 3063 | *const_val = *other_val; |
| 3065 | break; | 3064 | break; |
| 3065 | case CastOpPtrToInt: | ||
| 3066 | case CastOpIntToPtr: | ||
| 3067 | // can't do it | ||
| 3068 | break; | ||
| 3066 | case CastOpToUnknownSizeArray: | 3069 | case CastOpToUnknownSizeArray: |
| 3067 | { | 3070 | { |
| 3068 | TypeTableEntry *other_type = get_resolved_expr(expr_node)->type_entry; | 3071 | TypeTableEntry *other_type = get_resolved_expr(expr_node)->type_entry; |
| ... | @@ -3148,6 +3151,16 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3148,6 +3151,16 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3148 | return wanted_type; | 3151 | return wanted_type; |
| 3149 | } | 3152 | } |
| 3150 | 3153 | ||
| 3154 | |||
| 3155 | // explicit cast from isize or usize to pointer | ||
| 3156 | if (wanted_type->id == TypeTableEntryIdPointer && | ||
| 3157 | (actual_type == g->builtin_types.entry_isize || actual_type == g->builtin_types.entry_usize)) | ||
| 3158 | { | ||
| 3159 | node->data.fn_call_expr.cast_op = CastOpIntToPtr; | ||
| 3160 | eval_const_expr_implicit_cast(g, node, expr_node); | ||
| 3161 | return wanted_type; | ||
| 3162 | } | ||
| 3163 | |||
| 3151 | // explicit cast from any int to any other int | 3164 | // explicit cast from any int to any other int |
| 3152 | if (wanted_type->id == TypeTableEntryIdInt && | 3165 | if (wanted_type->id == TypeTableEntryIdInt && |
| 3153 | actual_type->id == TypeTableEntryIdInt) | 3166 | actual_type->id == TypeTableEntryIdInt) |
src/codegen.cpp+3| ... | @@ -428,6 +428,9 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { | ... | @@ -428,6 +428,9 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { |
| 428 | case CastOpPtrToInt: | 428 | case CastOpPtrToInt: |
| 429 | add_debug_source_node(g, node); | 429 | add_debug_source_node(g, node); |
| 430 | return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, ""); | 430 | return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, ""); |
| 431 | case CastOpIntToPtr: | ||
| 432 | add_debug_source_node(g, node); | ||
| 433 | return LLVMBuildIntToPtr(g->builder, expr_val, wanted_type->type_ref, ""); | ||
| 431 | case CastOpPointerReinterpret: | 434 | case CastOpPointerReinterpret: |
| 432 | add_debug_source_node(g, node); | 435 | add_debug_source_node(g, node); |
| 433 | return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, ""); | 436 | return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, ""); |
test/run_tests.cpp+13| ... | @@ -1303,6 +1303,19 @@ pub fn main(args: [][]u8) -> %void { | ... | @@ -1303,6 +1303,19 @@ pub fn main(args: [][]u8) -> %void { |
| 1303 | %%stdout.printf("BAD\n"); | 1303 | %%stdout.printf("BAD\n"); |
| 1304 | } | 1304 | } |
| 1305 | %%stdout.printf("OK\n"); | 1305 | %%stdout.printf("OK\n"); |
| 1306 | } | ||
| 1307 | )SOURCE", "OK\n"); | ||
| 1308 | |||
| 1309 | add_simple_case("int to ptr cast", R"SOURCE( | ||
| 1310 | import "std.zig"; | ||
| 1311 | pub fn main(args: [][]u8) -> %void { | ||
| 1312 | const x = isize(13); | ||
| 1313 | const y = (&u8)(x); | ||
| 1314 | const z = usize(y); | ||
| 1315 | if (z != 13) { | ||
| 1316 | %%stdout.printf("BAD\n"); | ||
| 1317 | } | ||
| 1318 | %%stdout.printf("OK\n"); | ||
| 1306 | } | 1319 | } |
| 1307 | )SOURCE", "OK\n"); | 1320 | )SOURCE", "OK\n"); |
| 1308 | } | 1321 | } |