authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-03-08 17:15:55-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-03-08 17:15:55-05:00
logaaf2230ae89d74497042b7fada8c8023bf274dbd
treefe6c2669f107c43d2d734aed73fd720293ffe416
parent028ec0f2c3574fb465ffe18f3022a7fa16f25ef6

fix partial inlining of binary math operator using old value

the code was abusing the internal IR API. fixed now. closes #699

2 files changed, 33 insertions(+), 8 deletions(-)

src/ir.cpp+8-8
......@@ -10595,9 +10595,9 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *
1059510595 if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) {
1059610596 ConstExprValue *op1_val = &op1->value;
1059710597 ConstExprValue *op2_val = &casted_op2->value;
10598 ConstExprValue *out_val = &bin_op_instruction->base.value;
10599
10600 bin_op_instruction->base.other = &bin_op_instruction->base;
10598 IrInstruction *result_instruction = ir_get_const(ira, &bin_op_instruction->base);
10599 ir_link_new_instruction(result_instruction, &bin_op_instruction->base);
10600 ConstExprValue *out_val = &result_instruction->value;
1060110601
1060210602 int err;
1060310603 if ((err = ir_eval_math_op(op1->value.type, op1_val, op_id, op2_val, out_val))) {
......@@ -10613,7 +10613,7 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *
1061310613 return ira->codegen->builtin_types.entry_invalid;
1061410614 }
1061510615
10616 ir_num_lit_fits_in_other_type(ira, &bin_op_instruction->base, op1->value.type, false);
10616 ir_num_lit_fits_in_other_type(ira, result_instruction, op1->value.type, false);
1061710617 return op1->value.type;
1061810618 } else if (op1->value.type->id == TypeTableEntryIdNumLitInt) {
1061910619 ir_add_error(ira, &bin_op_instruction->base,
......@@ -10765,9 +10765,9 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
1076510765 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) {
1076610766 ConstExprValue *op1_val = &casted_op1->value;
1076710767 ConstExprValue *op2_val = &casted_op2->value;
10768 ConstExprValue *out_val = &bin_op_instruction->base.value;
10769
10770 bin_op_instruction->base.other = &bin_op_instruction->base;
10768 IrInstruction *result_instruction = ir_get_const(ira, &bin_op_instruction->base);
10769 ir_link_new_instruction(result_instruction, &bin_op_instruction->base);
10770 ConstExprValue *out_val = &result_instruction->value;
1077110771
1077210772 int err;
1077310773 if ((err = ir_eval_math_op(resolved_type, op1_val, op_id, op2_val, out_val))) {
......@@ -10789,7 +10789,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
1078910789 return ira->codegen->builtin_types.entry_invalid;
1079010790 }
1079110791
10792 ir_num_lit_fits_in_other_type(ira, &bin_op_instruction->base, resolved_type, false);
10792 ir_num_lit_fits_in_other_type(ira, result_instruction, resolved_type, false);
1079310793 return resolved_type;
1079410794 }
1079510795
test/cases/eval.zig+25
......@@ -395,3 +395,28 @@ test "comptime slice of undefined pointer of length 0" {
395395 const slice2 = (&i32)(undefined)[100..100];
396396 assert(slice2.len == 0);
397397}
398
399fn copyWithPartialInline(s: []u32, b: []u8) void {
400 comptime var i: usize = 0;
401 inline while (i < 4) : (i += 1) {
402 s[i] = 0;
403 s[i] |= u32(b[i*4+0]) << 24;
404 s[i] |= u32(b[i*4+1]) << 16;
405 s[i] |= u32(b[i*4+2]) << 8;
406 s[i] |= u32(b[i*4+3]) << 0;
407 }
408}
409
410test "binary math operator in partially inlined function" {
411 var s: [4]u32 = undefined;
412 var b: [16]u8 = undefined;
413
414 for (b) |*r, i|
415 *r = u8(i + 1);
416
417 copyWithPartialInline(s[0..], b[0..]);
418 assert(s[0] == 0x1020304);
419 assert(s[1] == 0x5060708);
420 assert(s[2] == 0x90a0b0c);
421 assert(s[3] == 0xd0e0f10);
422}