mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Dynamic protocols. Correctly widen unsigned array indices (see #1029)
This commit is contained in:
committed by
Christoffer Lerno
parent
49c4595457
commit
70f906c71a
@@ -173,6 +173,7 @@
|
||||
- Added posix socket functions.
|
||||
|
||||
### Fixes
|
||||
- Indexing into arrays would not always widen the index safely.
|
||||
- Macros with implicit return didn't correctly deduct the return type.
|
||||
- Reevaluating a bitstruct (due to checked) would break.
|
||||
- Fix missing comparison between `any`.
|
||||
|
||||
@@ -606,7 +606,7 @@ static inline void llvm_emit_subscript_addr_with_base(GenContext *c, BEValue *re
|
||||
case TYPE_VECTOR:
|
||||
{
|
||||
AlignSize alignment;
|
||||
LLVMValueRef ptr = llvm_emit_array_gep_raw_index(c, parent->value, llvm_get_type(c, type), index->value, parent->alignment, &alignment);
|
||||
LLVMValueRef ptr = llvm_emit_array_gep_raw_index(c, parent->value, llvm_get_type(c, type), index, parent->alignment, &alignment);
|
||||
llvm_value_set_address(result, ptr, type->array.base, alignment);
|
||||
return;
|
||||
}
|
||||
@@ -1167,7 +1167,7 @@ static inline void llvm_emit_access_addr(GenContext *c, BEValue *be_value, Expr
|
||||
LLVMTypeRef value_type = llvm_get_type(c, type_get_array(member->type, vec_size(flat_type->decl->enums.values)));
|
||||
AlignSize align = LLVMGetAlignment(member->backend_ref);
|
||||
AlignSize alignment;
|
||||
LLVMValueRef ptr = llvm_emit_array_gep_raw_index(c, member->backend_ref, value_type, be_value->value, align, &alignment);
|
||||
LLVMValueRef ptr = llvm_emit_array_gep_raw_index(c, member->backend_ref, value_type, be_value, align, &alignment);
|
||||
llvm_value_set_address(be_value, ptr, member->type, alignment);
|
||||
return;
|
||||
}
|
||||
@@ -2966,7 +2966,7 @@ static void gencontext_emit_slice(GenContext *c, BEValue *be_value, Expr *expr)
|
||||
{
|
||||
// Move pointer
|
||||
AlignSize alignment;
|
||||
start_pointer = llvm_emit_array_gep_raw_index(c, parent.value, llvm_get_type(c, parent.type), start.value, type_abi_alignment(parent.type), &alignment);
|
||||
start_pointer = llvm_emit_array_gep_raw_index(c, parent.value, llvm_get_type(c, parent.type), &start, type_abi_alignment(parent.type), &alignment);
|
||||
break;
|
||||
}
|
||||
case TYPE_SUBARRAY:
|
||||
@@ -3656,12 +3656,13 @@ static void llvm_emit_array_comp(GenContext *c, BEValue *be_value, BEValue *lhs,
|
||||
|
||||
AlignSize align_lhs;
|
||||
BEValue lhs_v;
|
||||
LLVMValueRef index = llvm_load_value(c, &index_var);
|
||||
LLVMValueRef lhs_ptr = llvm_emit_array_gep_raw_index(c, lhs->value, array_type, index, lhs->alignment, &align_lhs);
|
||||
BEValue index_copy = index_var;
|
||||
llvm_value_rvalue(c, &index_copy);
|
||||
LLVMValueRef lhs_ptr = llvm_emit_array_gep_raw_index(c, lhs->value, array_type, &index_copy, lhs->alignment, &align_lhs);
|
||||
llvm_value_set_address(&lhs_v, lhs_ptr, array_base_type, align_lhs);
|
||||
AlignSize align_rhs;
|
||||
BEValue rhs_v;
|
||||
LLVMValueRef rhs_ptr = llvm_emit_array_gep_raw_index(c, rhs->value, array_type, index, rhs->alignment, &align_rhs);
|
||||
LLVMValueRef rhs_ptr = llvm_emit_array_gep_raw_index(c, rhs->value, array_type, &index_copy, rhs->alignment, &align_rhs);
|
||||
llvm_value_set_address(&rhs_v, rhs_ptr, array_base_type, align_rhs);
|
||||
BEValue comp;
|
||||
llvm_emit_comp(c, &comp, &lhs_v, &rhs_v, BINARYOP_EQ);
|
||||
@@ -3669,7 +3670,7 @@ static void llvm_emit_array_comp(GenContext *c, BEValue *be_value, BEValue *lhs,
|
||||
llvm_emit_cond_br(c, &comp, comparison, exit);
|
||||
llvm_emit_block(c, comparison);
|
||||
|
||||
LLVMValueRef new_index = LLVMBuildAdd(c->builder, index, one, "inc");
|
||||
LLVMValueRef new_index = LLVMBuildAdd(c->builder, index_copy.value, one, "inc");
|
||||
llvm_store_raw(c, &index_var, new_index);
|
||||
llvm_emit_int_comp_raw(c, &comp, type_usz, type_usz, new_index, len_val, BINARYOP_LT);
|
||||
comparison_phi = c->current_block;
|
||||
@@ -4948,16 +4949,26 @@ LLVMValueRef llvm_emit_struct_gep_raw(GenContext *context, LLVMValueRef ptr, LLV
|
||||
}
|
||||
|
||||
|
||||
LLVMValueRef llvm_emit_array_gep_raw_index(GenContext *c, LLVMValueRef ptr, LLVMTypeRef array_type, LLVMValueRef index, AlignSize array_alignment, AlignSize *alignment)
|
||||
LLVMValueRef llvm_emit_array_gep_raw_index(GenContext *c, LLVMValueRef ptr, LLVMTypeRef array_type, BEValue *index, AlignSize array_alignment, AlignSize *alignment)
|
||||
{
|
||||
LLVMValueRef index_val = llvm_load_value(c, index);
|
||||
Type *index_type = index->type;
|
||||
assert(type_is_integer(index_type));
|
||||
if (type_is_unsigned(index_type) && type_size(index_type) < type_size(type_usz))
|
||||
{
|
||||
index_type = type_usz->canonical;
|
||||
index_val = llvm_zext_trunc(c, index_val, llvm_get_type(c, index_type));
|
||||
}
|
||||
*alignment = type_min_alignment(llvm_store_size(c, LLVMGetElementType(array_type)), array_alignment);
|
||||
LLVMValueRef idx[2] = { llvm_get_zero_raw(LLVMTypeOf(index)), index };
|
||||
LLVMValueRef idx[2] = { llvm_get_zero(c, index_type), index_val };
|
||||
return LLVMBuildInBoundsGEP2(c->builder, array_type, ptr, idx, 2, "");
|
||||
}
|
||||
|
||||
LLVMValueRef llvm_emit_array_gep_raw(GenContext *c, LLVMValueRef ptr, LLVMTypeRef array_type, unsigned index, AlignSize array_alignment, AlignSize *alignment)
|
||||
{
|
||||
return llvm_emit_array_gep_raw_index(c, ptr, array_type, llvm_const_int(c, type_usz, index), array_alignment, alignment);
|
||||
BEValue index_value;
|
||||
llvm_value_set(&index_value, llvm_const_int(c, type_usz, index), type_usz);
|
||||
return llvm_emit_array_gep_raw_index(c, ptr, array_type, &index_value, array_alignment, alignment);
|
||||
}
|
||||
|
||||
LLVMValueRef llvm_emit_pointer_gep_raw(GenContext *c, LLVMTypeRef pointee_type, LLVMValueRef ptr, LLVMValueRef offset)
|
||||
|
||||
@@ -452,7 +452,7 @@ LLVMValueRef llvm_emit_aggregate_two(GenContext *c, Type *type, LLVMValueRef val
|
||||
LLVMValueRef llvm_emit_struct_gep_raw(GenContext *context, LLVMValueRef ptr, LLVMTypeRef struct_type, unsigned index,
|
||||
unsigned struct_alignment, AlignSize *alignment);
|
||||
LLVMValueRef llvm_emit_array_gep_raw(GenContext *c, LLVMValueRef ptr, LLVMTypeRef array_type, unsigned index, AlignSize array_alignment, AlignSize *alignment);
|
||||
LLVMValueRef llvm_emit_array_gep_raw_index(GenContext *c, LLVMValueRef ptr, LLVMTypeRef array_type, LLVMValueRef index, AlignSize array_alignment, AlignSize *alignment);
|
||||
LLVMValueRef llvm_emit_array_gep_raw_index(GenContext *c, LLVMValueRef ptr, LLVMTypeRef array_type, BEValue *index, AlignSize array_alignment, AlignSize *alignment);
|
||||
LLVMValueRef llvm_emit_pointer_gep_raw(GenContext *c, LLVMTypeRef pointee_type, LLVMValueRef ptr, LLVMValueRef offset);
|
||||
LLVMValueRef llvm_emit_pointer_inbounds_gep_raw(GenContext *c, LLVMTypeRef pointee_type, LLVMValueRef ptr, LLVMValueRef offset);
|
||||
LLVMValueRef llvm_emit_pointer_inbounds_gep_raw_index(GenContext *c, LLVMTypeRef pointee_type, LLVMValueRef ptr, ByteSize offset);
|
||||
|
||||
@@ -39,16 +39,20 @@ entry:
|
||||
store i32 1, ptr %f, align 4
|
||||
store i32 0, ptr %g, align 4
|
||||
%0 = load i32, ptr %f, align 4
|
||||
%1 = getelementptr inbounds [2 x i32], ptr @"test.Foo$val", i32 0, i32 %0
|
||||
%zext = zext i32 %0 to i64
|
||||
%1 = getelementptr inbounds [2 x i32], ptr @"test.Foo$val", i64 0, i64 %zext
|
||||
%2 = load i32, ptr %1, align 4
|
||||
%3 = load i32, ptr %f, align 4
|
||||
%4 = getelementptr inbounds [2 x ptr], ptr @"test.Foo$testme", i32 0, i32 %3
|
||||
%zext1 = zext i32 %3 to i64
|
||||
%4 = getelementptr inbounds [2 x ptr], ptr @"test.Foo$testme", i64 0, i64 %zext1
|
||||
%5 = load ptr, ptr %4, align 8
|
||||
%6 = load i32, ptr %g, align 4
|
||||
%7 = getelementptr inbounds [2 x i32], ptr @"test.Foo$val", i32 0, i32 %6
|
||||
%zext2 = zext i32 %6 to i64
|
||||
%7 = getelementptr inbounds [2 x i32], ptr @"test.Foo$val", i64 0, i64 %zext2
|
||||
%8 = load i32, ptr %7, align 4
|
||||
%9 = load i32, ptr %g, align 4
|
||||
%10 = getelementptr inbounds [2 x ptr], ptr @"test.Foo$testme", i32 0, i32 %9
|
||||
%zext3 = zext i32 %9 to i64
|
||||
%10 = getelementptr inbounds [2 x ptr], ptr @"test.Foo$testme", i64 0, i64 %zext3
|
||||
%11 = load ptr, ptr %10, align 8
|
||||
%12 = call i32 (ptr, ...) @printf(ptr @.str.2, i32 %2, ptr %5, i32 %8, ptr %11)
|
||||
ret void
|
||||
|
||||
Reference in New Issue
Block a user