add explicit cast from isize/usize to pointer

closes #91
This commit is contained in:
Andrew Kelley 2016-01-27 12:43:03 -07:00
parent e809baa866
commit 261517aa44
4 changed files with 31 additions and 1 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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, "");

View File

@ -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");
}