Skip to content

Commit

Permalink
Cast array indexes to long (#460)
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli authored Dec 16, 2023
1 parent fae5e3d commit 06c74f5
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 15 deletions.
12 changes: 9 additions & 3 deletions self_hosted/typecheck.jou
Original file line number Diff line number Diff line change
Expand Up @@ -1026,11 +1026,17 @@ class Stage3TypeChecker:
snprintf(message, sizeof message[0], "value of type %s cannot be indexed", types->original_type->name)
fail(pointer->location, message)

index_type = self->do_expression(index)->original_type
if not index_type->is_integer_type():
snprintf(message, sizeof message[0], "the index inside [...] must be an integer, not %s", index_type->name)
index_types = self->do_expression(index)
assert index_types != NULL

if not index_types->original_type->is_integer_type():
snprintf(message, sizeof message[0], "the index inside [...] must be an integer, not %s", index_types->original_type->name)
fail(index->location, message)

# LLVM assumes that indexes smaller than 64 bits are signed.
# https://github.com/Akuli/jou/issues/48
index_types->do_implicit_cast(long_type, Location{}, NULL)

return pointer_type->value_type

def do_expression_maybe_void(self, expression: AstExpression*) -> ExpressionTypes*:
Expand Down
10 changes: 1 addition & 9 deletions src/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,15 +336,7 @@ static void codegen_instruction(const struct State *st, const CfInstruction *ins
}
break;
case CF_PTR_ADD_INT:
{
LLVMValueRef index = getop(1);
if (ins->operands[1]->type->kind == TYPE_UNSIGNED_INTEGER) {
// https://github.com/Akuli/jou/issues/48
// Apparently the default is to interpret indexes as signed.
index = LLVMBuildZExt(st->builder, index, LLVMInt64Type(), "ptr_add_int_implicit_cast");
}
setdest(LLVMBuildGEP(st->builder, getop(0), &index, 1, "ptr_add_int"));
}
setdest(LLVMBuildGEP(st->builder, getop(0), (LLVMValueRef[]){getop(1)}, 1, "ptr_add_int"));
break;
case CF_NUM_CAST:
{
Expand Down
10 changes: 7 additions & 3 deletions src/typecheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -756,14 +756,18 @@ static const Type *typecheck_indexing(
}
assert(ptrtype->kind == TYPE_POINTER);

const Type *indextype = typecheck_expression_not_void(ft, indexexpr)->type;
if (!is_integer_type(indextype)) {
ExpressionTypes *indextypes = typecheck_expression_not_void(ft, indexexpr);
if (!is_integer_type(indextypes->type)) {
fail_with_error(
indexexpr->location,
"the index inside [...] must be an integer, not %s",
indextype->name);
indextypes->type->name);
}

// LLVM assumes that indexes smaller than 64 bits are signed.
// https://github.com/Akuli/jou/issues/48
do_implicit_cast(indextypes, longType, (Location){0}, NULL);

return ptrtype->data.valuetype;
}

Expand Down

0 comments on commit 06c74f5

Please sign in to comment.