| 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 | 325 | CastOpNoCast, // signifies the function call expression is not a cast |
| 326 | 326 | CastOpNoop, // fn call expr is a cast, but does nothing |
| 327 | 327 | CastOpPtrToInt, |
| 328 | CastOpIntToPtr, | |
| 328 | 329 | CastOpIntWidenOrShorten, |
| 329 | 330 | CastOpToUnknownSizeArray, |
| 330 | 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 | 3058 | case CastOpNoCast: |
| 3059 | 3059 | zig_unreachable(); |
| 3060 | 3060 | case CastOpNoop: |
| 3061 | case CastOpPtrToInt: | |
| 3062 | 3061 | case CastOpIntWidenOrShorten: |
| 3063 | 3062 | case CastOpPointerReinterpret: |
| 3064 | 3063 | *const_val = *other_val; |
| 3065 | 3064 | break; |
| 3065 | case CastOpPtrToInt: | |
| 3066 | case CastOpIntToPtr: | |
| 3067 | // can't do it | |
| 3068 | break; | |
| 3066 | 3069 | case CastOpToUnknownSizeArray: |
| 3067 | 3070 | { |
| 3068 | 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 | 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 | 3164 | // explicit cast from any int to any other int |
| 3152 | 3165 | if (wanted_type->id == TypeTableEntryIdInt && |
| 3153 | 3166 | actual_type->id == TypeTableEntryIdInt) |
src/codegen.cpp+3| ... | ... | @@ -428,6 +428,9 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { |
| 428 | 428 | case CastOpPtrToInt: |
| 429 | 429 | add_debug_source_node(g, node); |
| 430 | 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 | 434 | case CastOpPointerReinterpret: |
| 432 | 435 | add_debug_source_node(g, node); |
| 433 | 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 | 1303 | %%stdout.printf("BAD\n"); |
| 1304 | 1304 | } |
| 1305 | 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 | 1320 | )SOURCE", "OK\n"); |
| 1308 | 1321 | } |