Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add array to void* implicit cast #541

Merged
merged 2 commits into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion self_hosted/typecheck.jou
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def can_cast_implicitly(from: Type*, to: Type*) -> bool:
return (
from == to
or (from->kind == TypeKind::Array and to->kind == TypeKind::Pointer and from->array.item_type == to->value_type)
or (from->kind == TypeKind::Array and to->kind == TypeKind::VoidPointer)
or (
from->is_integer_type()
and to->is_integer_type()
Expand All @@ -46,6 +47,7 @@ def can_cast_explicitly(from: Type*, to: Type*) -> bool:
return (
from == to
or (from->kind == TypeKind::Array and to->kind == TypeKind::Pointer and from->array.item_type == to->value_type)
or (from->kind == TypeKind::Array and to->kind == TypeKind::VoidPointer)
or (from->is_pointer_type() and to->is_pointer_type())
or (from->is_number_type() and to->is_number_type())
or (from->is_integer_type() and to->kind == TypeKind::Enum)
Expand Down Expand Up @@ -165,7 +167,7 @@ class ExpressionTypes:
fail_with_implicit_cast_error(error_location, error_template, from, to)

self->implicit_cast_type = to
if from->kind == TypeKind::Array and to->kind == TypeKind::Pointer:
if from->kind == TypeKind::Array and to->is_pointer_type():
self->implicit_array_to_pointer_cast = True
ensure_can_take_address(
self->expression,
Expand Down
8 changes: 6 additions & 2 deletions src/typecheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,11 @@ static bool can_cast_implicitly(const Type *from, const Type *to)
return
from == to
|| (
// array to pointer implicitly
// array to pointer with same item type
from->kind == TYPE_ARRAY && to->kind == TYPE_POINTER && from->data.array.membertype == to->data.valuetype
) || (
// array to void*
from->kind == TYPE_ARRAY && to->kind == TYPE_VOID_POINTER
) || (
// Cast to bigger integer types implicitly, unless it is signed-->unsigned.
is_integer_type(from)
Expand Down Expand Up @@ -594,7 +597,7 @@ static void do_implicit_cast(
fail_with_implicit_cast_error(location, errormsg_template, from, to);

types->implicit_cast_type = to;
types->implicit_array_to_pointer_cast = (from->kind == TYPE_ARRAY && to->kind == TYPE_POINTER);
types->implicit_array_to_pointer_cast = (from->kind == TYPE_ARRAY && is_pointer_type(to));
if (types->implicit_array_to_pointer_cast)
ensure_can_take_address(
fom,
Expand All @@ -620,6 +623,7 @@ static void do_explicit_cast(const FunctionOrMethodTypes *fom, ExpressionTypes *
if (
from != to
&& !(from->kind == TYPE_ARRAY && to->kind == TYPE_POINTER && from->data.array.membertype == to->data.valuetype)
&& !(from->kind == TYPE_ARRAY && to->kind == TYPE_VOID_POINTER)
&& !(is_pointer_type(from) && is_pointer_type(to))
&& !(is_number_type(from) && is_number_type(to))
&& !(is_integer_type(from) && to->kind == TYPE_ENUM)
Expand Down
17 changes: 17 additions & 0 deletions tests/should_succeed/array_to_voidptr.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import "stdlib/io.jou"
import "stdlib/mem.jou"


def main() -> int:
# Implicit cast
array = [1, 2, 3, 4]
p: void* = array
memset(p, 0, 4)
printf("[%d, %d, %d]\n", array[0], array[1], array[2]) # Output: [0, 2, 3]

# Explicit cast
array = [1, 2, 3, 4]
memset(array as void*, 0, 4)
printf("[%d, %d, %d]\n", array[0], array[1], array[2]) # Output: [0, 2, 3]

return 0
Loading