mirror of
https://github.com/ziglang/zig.git
synced 2026-02-15 13:58:27 +00:00
fix handling of const values for 2d arrays
This commit is contained in:
parent
c7591736b4
commit
4cbeb87e83
@ -81,6 +81,11 @@ struct ConstArrayValue {
|
||||
// This will be the same as `len` from the type, but we duplicate the information
|
||||
// in the constant value so that pointers pointing to arrays can see this size.
|
||||
size_t size;
|
||||
// If the data for this array is supposed to be contained in a different constant
|
||||
// value, we link to the parent here. This way getting a pointer to this constant
|
||||
// value can return a pointer into the parent data structure.
|
||||
ConstExprValue *parent_array;
|
||||
size_t parent_array_index;
|
||||
};
|
||||
|
||||
enum ConstPtrSpecial {
|
||||
|
||||
@ -2412,6 +2412,25 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {
|
||||
}
|
||||
}
|
||||
|
||||
static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) {
|
||||
ConstExprValue *parent_array = array_const_val->data.x_array.parent_array;
|
||||
LLVMValueRef base_ptr;
|
||||
if (parent_array) {
|
||||
size_t parent_array_index = array_const_val->data.x_array.parent_array_index;
|
||||
base_ptr = gen_const_ptr_array_recursive(g, parent_array, parent_array_index);
|
||||
} else {
|
||||
render_const_val(g, array_const_val);
|
||||
render_const_val_global(g, array_const_val);
|
||||
base_ptr = array_const_val->llvm_global;
|
||||
}
|
||||
TypeTableEntry *usize = g->builtin_types.entry_usize;
|
||||
LLVMValueRef indices[] = {
|
||||
LLVMConstNull(usize->type_ref),
|
||||
LLVMConstInt(usize->type_ref, index, false),
|
||||
};
|
||||
return LLVMConstInBoundsGEP(base_ptr, indices, 2);
|
||||
}
|
||||
|
||||
static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
|
||||
TypeTableEntry *canon_type = get_underlying_type(const_val->type);
|
||||
assert(!canon_type->zero_bits);
|
||||
@ -2554,7 +2573,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
|
||||
render_const_val_global(g, const_val);
|
||||
size_t index = const_val->data.x_ptr.index;
|
||||
ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr;
|
||||
TypeTableEntry *usize = g->builtin_types.entry_usize;
|
||||
if (base_ptr) {
|
||||
if (index == SIZE_MAX) {
|
||||
render_const_val(g, base_ptr);
|
||||
@ -2568,25 +2586,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
|
||||
assert(array_const_val->type->id == TypeTableEntryIdArray);
|
||||
if (array_const_val->type->zero_bits) {
|
||||
// make this a null pointer
|
||||
TypeTableEntry *usize_type = g->builtin_types.entry_usize;
|
||||
const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize_type->type_ref),
|
||||
TypeTableEntry *usize = g->builtin_types.entry_usize;
|
||||
const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
|
||||
const_val->type->type_ref);
|
||||
render_const_val_global(g, const_val);
|
||||
return const_val->llvm_value;
|
||||
}
|
||||
render_const_val(g, array_const_val);
|
||||
render_const_val_global(g, array_const_val);
|
||||
LLVMValueRef indices[] = {
|
||||
LLVMConstNull(usize->type_ref),
|
||||
LLVMConstInt(usize->type_ref, index, false),
|
||||
};
|
||||
LLVMValueRef uncasted_ptr_val = LLVMConstInBoundsGEP(array_const_val->llvm_global, indices, 2);
|
||||
LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, index);
|
||||
LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
|
||||
const_val->llvm_value = ptr_val;
|
||||
render_const_val_global(g, const_val);
|
||||
return ptr_val;
|
||||
}
|
||||
} else {
|
||||
TypeTableEntry *usize = g->builtin_types.entry_usize;
|
||||
const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, index, false), const_val->type->type_ref);
|
||||
render_const_val_global(g, const_val);
|
||||
return const_val->llvm_value;
|
||||
|
||||
@ -8314,7 +8314,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
||||
bool safety_check_on = elem_ptr_instruction->safety_check_on;
|
||||
if (casted_elem_index->value.special != ConstValSpecialRuntime) {
|
||||
if (instr_is_comptime(casted_elem_index)) {
|
||||
uint64_t index = casted_elem_index->value.data.x_bignum.data.x_uint;
|
||||
if (array_type->id == TypeTableEntryIdArray) {
|
||||
uint64_t array_len = array_type->data.array.len;
|
||||
@ -9923,6 +9923,13 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
|
||||
if (const_val.special == ConstValSpecialStatic) {
|
||||
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, const_val.depends_on_compile_var);
|
||||
*out_val = const_val;
|
||||
for (size_t i = 0; i < elem_count; i += 1) {
|
||||
ConstExprValue *elem_val = &out_val->data.x_array.elements[i];
|
||||
if (elem_val->type->id == TypeTableEntryIdArray) {
|
||||
elem_val->data.x_array.parent_array = out_val;
|
||||
elem_val->data.x_array.parent_array_index = i;
|
||||
}
|
||||
}
|
||||
return fixed_size_array_type;
|
||||
}
|
||||
|
||||
|
||||
@ -500,3 +500,20 @@ fn nonConstPtrToAliasedType() {
|
||||
const int = i32;
|
||||
assert(?&int == ?&i32);
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn array2DConstDoublePtr() {
|
||||
@setFnTest(this);
|
||||
|
||||
const rect_2d_vertexes = [][1]f32 {
|
||||
[]f32{1.0},
|
||||
[]f32{2.0},
|
||||
};
|
||||
testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
|
||||
}
|
||||
|
||||
fn testArray2DConstDoublePtr(ptr: &const f32) {
|
||||
assert(ptr[0] == 1.0);
|
||||
assert(ptr[1] == 2.0);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user