authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-16 12:42:46-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-16 12:42:46-05:00
log4cbeb87e83135e0a1ecbfb90170761ad6e5adb7a
treeb95b6e7a7723280c7f9ae7be17ff748f4f2cfaa0
parentc7591736b4ae3aed90f6980b4cb23a4dab21d925

fix handling of const values for 2d arrays


4 files changed, 53 insertions(+), 11 deletions(-)

src/all_types.hpp+5
......@@ -81,6 +81,11 @@ struct ConstArrayValue {
8181 // This will be the same as `len` from the type, but we duplicate the information
8282 // in the constant value so that pointers pointing to arrays can see this size.
8383 size_t size;
84 // If the data for this array is supposed to be contained in a different constant
85 // value, we link to the parent here. This way getting a pointer to this constant
86 // value can return a pointer into the parent data structure.
87 ConstExprValue *parent_array;
88 size_t parent_array_index;
8489};
8590
8691enum ConstPtrSpecial {
src/codegen.cpp+23-10
......@@ -2412,6 +2412,25 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {
24122412 }
24132413}
24142414
2415static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) {
2416 ConstExprValue *parent_array = array_const_val->data.x_array.parent_array;
2417 LLVMValueRef base_ptr;
2418 if (parent_array) {
2419 size_t parent_array_index = array_const_val->data.x_array.parent_array_index;
2420 base_ptr = gen_const_ptr_array_recursive(g, parent_array, parent_array_index);
2421 } else {
2422 render_const_val(g, array_const_val);
2423 render_const_val_global(g, array_const_val);
2424 base_ptr = array_const_val->llvm_global;
2425 }
2426 TypeTableEntry *usize = g->builtin_types.entry_usize;
2427 LLVMValueRef indices[] = {
2428 LLVMConstNull(usize->type_ref),
2429 LLVMConstInt(usize->type_ref, index, false),
2430 };
2431 return LLVMConstInBoundsGEP(base_ptr, indices, 2);
2432}
2433
24152434static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
24162435 TypeTableEntry *canon_type = get_underlying_type(const_val->type);
24172436 assert(!canon_type->zero_bits);
......@@ -2554,7 +2573,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
25542573 render_const_val_global(g, const_val);
25552574 size_t index = const_val->data.x_ptr.index;
25562575 ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr;
2557 TypeTableEntry *usize = g->builtin_types.entry_usize;
25582576 if (base_ptr) {
25592577 if (index == SIZE_MAX) {
25602578 render_const_val(g, base_ptr);
......@@ -2568,25 +2586,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
25682586 assert(array_const_val->type->id == TypeTableEntryIdArray);
25692587 if (array_const_val->type->zero_bits) {
25702588 // make this a null pointer
2571 TypeTableEntry *usize_type = g->builtin_types.entry_usize;
2572 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize_type->type_ref),
2589 TypeTableEntry *usize = g->builtin_types.entry_usize;
2590 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
25732591 const_val->type->type_ref);
25742592 render_const_val_global(g, const_val);
25752593 return const_val->llvm_value;
25762594 }
2577 render_const_val(g, array_const_val);
2578 render_const_val_global(g, array_const_val);
2579 LLVMValueRef indices[] = {
2580 LLVMConstNull(usize->type_ref),
2581 LLVMConstInt(usize->type_ref, index, false),
2582 };
2583 LLVMValueRef uncasted_ptr_val = LLVMConstInBoundsGEP(array_const_val->llvm_global, indices, 2);
2595 LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, index);
25842596 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
25852597 const_val->llvm_value = ptr_val;
25862598 render_const_val_global(g, const_val);
25872599 return ptr_val;
25882600 }
25892601 } else {
2602 TypeTableEntry *usize = g->builtin_types.entry_usize;
25902603 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, index, false), const_val->type->type_ref);
25912604 render_const_val_global(g, const_val);
25922605 return const_val->llvm_value;
src/ir.cpp+8-1
......@@ -8314,7 +8314,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
83148314 return ira->codegen->builtin_types.entry_invalid;
83158315
83168316 bool safety_check_on = elem_ptr_instruction->safety_check_on;
8317 if (casted_elem_index->value.special != ConstValSpecialRuntime) {
8317 if (instr_is_comptime(casted_elem_index)) {
83188318 uint64_t index = casted_elem_index->value.data.x_bignum.data.x_uint;
83198319 if (array_type->id == TypeTableEntryIdArray) {
83208320 uint64_t array_len = array_type->data.array.len;
......@@ -9923,6 +9923,13 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
99239923 if (const_val.special == ConstValSpecialStatic) {
99249924 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, const_val.depends_on_compile_var);
99259925 *out_val = const_val;
9926 for (size_t i = 0; i < elem_count; i += 1) {
9927 ConstExprValue *elem_val = &out_val->data.x_array.elements[i];
9928 if (elem_val->type->id == TypeTableEntryIdArray) {
9929 elem_val->data.x_array.parent_array = out_val;
9930 elem_val->data.x_array.parent_array_index = i;
9931 }
9932 }
99269933 return fixed_size_array_type;
99279934 }
99289935
test/cases/misc.zig+17
......@@ -500,3 +500,20 @@ fn nonConstPtrToAliasedType() {
500500 const int = i32;
501501 assert(?&int == ?&i32);
502502}
503
504
505
506fn array2DConstDoublePtr() {
507 @setFnTest(this);
508
509 const rect_2d_vertexes = [][1]f32 {
510 []f32{1.0},
511 []f32{2.0},
512 };
513 testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
514}
515
516fn testArray2DConstDoublePtr(ptr: &const f32) {
517 assert(ptr[0] == 1.0);
518 assert(ptr[1] == 2.0);
519}