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 {...@@ -81,6 +81,11 @@ struct ConstArrayValue {
81 // This will be the same as `len` from the type, but we duplicate the information81 // This will be the same as `len` from the type, but we duplicate the information
82 // in the constant value so that pointers pointing to arrays can see this size.82 // in the constant value so that pointers pointing to arrays can see this size.
83 size_t size;83 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;
84};89};
8590
86enum ConstPtrSpecial {91enum ConstPtrSpecial {
src/codegen.cpp+23-10
...@@ -2412,6 +2412,25 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {...@@ -2412,6 +2412,25 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {
2412 }2412 }
2413}2413}
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
2415static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {2434static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
2416 TypeTableEntry *canon_type = get_underlying_type(const_val->type);2435 TypeTableEntry *canon_type = get_underlying_type(const_val->type);
2417 assert(!canon_type->zero_bits);2436 assert(!canon_type->zero_bits);
...@@ -2554,7 +2573,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -2554,7 +2573,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
2554 render_const_val_global(g, const_val);2573 render_const_val_global(g, const_val);
2555 size_t index = const_val->data.x_ptr.index;2574 size_t index = const_val->data.x_ptr.index;
2556 ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr;2575 ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr;
2557 TypeTableEntry *usize = g->builtin_types.entry_usize;
2558 if (base_ptr) {2576 if (base_ptr) {
2559 if (index == SIZE_MAX) {2577 if (index == SIZE_MAX) {
2560 render_const_val(g, base_ptr);2578 render_const_val(g, base_ptr);
...@@ -2568,25 +2586,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -2568,25 +2586,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
2568 assert(array_const_val->type->id == TypeTableEntryIdArray);2586 assert(array_const_val->type->id == TypeTableEntryIdArray);
2569 if (array_const_val->type->zero_bits) {2587 if (array_const_val->type->zero_bits) {
2570 // make this a null pointer2588 // make this a null pointer
2571 TypeTableEntry *usize_type = g->builtin_types.entry_usize;2589 TypeTableEntry *usize = g->builtin_types.entry_usize;
2572 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize_type->type_ref),2590 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
2573 const_val->type->type_ref);2591 const_val->type->type_ref);
2574 render_const_val_global(g, const_val);2592 render_const_val_global(g, const_val);
2575 return const_val->llvm_value;2593 return const_val->llvm_value;
2576 }2594 }
2577 render_const_val(g, array_const_val);2595 LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, index);
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);
2584 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);2596 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
2585 const_val->llvm_value = ptr_val;2597 const_val->llvm_value = ptr_val;
2586 render_const_val_global(g, const_val);2598 render_const_val_global(g, const_val);
2587 return ptr_val;2599 return ptr_val;
2588 }2600 }
2589 } else {2601 } else {
2602 TypeTableEntry *usize = g->builtin_types.entry_usize;
2590 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, index, false), const_val->type->type_ref);2603 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, index, false), const_val->type->type_ref);
2591 render_const_val_global(g, const_val);2604 render_const_val_global(g, const_val);
2592 return const_val->llvm_value;2605 return const_val->llvm_value;
src/ir.cpp+8-1
...@@ -8314,7 +8314,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -8314,7 +8314,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
8314 return ira->codegen->builtin_types.entry_invalid;8314 return ira->codegen->builtin_types.entry_invalid;
83158315
8316 bool safety_check_on = elem_ptr_instruction->safety_check_on;8316 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)) {
8318 uint64_t index = casted_elem_index->value.data.x_bignum.data.x_uint;8318 uint64_t index = casted_elem_index->value.data.x_bignum.data.x_uint;
8319 if (array_type->id == TypeTableEntryIdArray) {8319 if (array_type->id == TypeTableEntryIdArray) {
8320 uint64_t array_len = array_type->data.array.len;8320 uint64_t array_len = array_type->data.array.len;
...@@ -9923,6 +9923,13 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -9923,6 +9923,13 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
9923 if (const_val.special == ConstValSpecialStatic) {9923 if (const_val.special == ConstValSpecialStatic) {
9924 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, const_val.depends_on_compile_var);9924 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, const_val.depends_on_compile_var);
9925 *out_val = const_val;9925 *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 }
9926 return fixed_size_array_type;9933 return fixed_size_array_type;
9927 }9934 }
99289935
test/cases/misc.zig+17
...@@ -500,3 +500,20 @@ fn nonConstPtrToAliasedType() {...@@ -500,3 +500,20 @@ fn nonConstPtrToAliasedType() {
500 const int = i32;500 const int = i32;
501 assert(?&int == ?&i32);501 assert(?&int == ?&i32);
502}502}
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}