Skip to content

Commit

Permalink
fix partial inlining of binary math operator using old value
Browse files Browse the repository at this point in the history
the code was abusing the internal IR API. fixed now.

closes #699
  • Loading branch information
andrewrk committed Mar 8, 2018
1 parent 028ec0f commit aaf2230
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 8 deletions.
16 changes: 8 additions & 8 deletions src/ir.cpp
Expand Up @@ -10595,9 +10595,9 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *
if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) {
ConstExprValue *op1_val = &op1->value;
ConstExprValue *op2_val = &casted_op2->value;
ConstExprValue *out_val = &bin_op_instruction->base.value;

bin_op_instruction->base.other = &bin_op_instruction->base;
IrInstruction *result_instruction = ir_get_const(ira, &bin_op_instruction->base);
ir_link_new_instruction(result_instruction, &bin_op_instruction->base);
ConstExprValue *out_val = &result_instruction->value;

int err;
if ((err = ir_eval_math_op(op1->value.type, op1_val, op_id, op2_val, out_val))) {
Expand All @@ -10613,7 +10613,7 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *
return ira->codegen->builtin_types.entry_invalid;
}

ir_num_lit_fits_in_other_type(ira, &bin_op_instruction->base, op1->value.type, false);
ir_num_lit_fits_in_other_type(ira, result_instruction, op1->value.type, false);
return op1->value.type;
} else if (op1->value.type->id == TypeTableEntryIdNumLitInt) {
ir_add_error(ira, &bin_op_instruction->base,
Expand Down Expand Up @@ -10765,9 +10765,9 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) {
ConstExprValue *op1_val = &casted_op1->value;
ConstExprValue *op2_val = &casted_op2->value;
ConstExprValue *out_val = &bin_op_instruction->base.value;

bin_op_instruction->base.other = &bin_op_instruction->base;
IrInstruction *result_instruction = ir_get_const(ira, &bin_op_instruction->base);
ir_link_new_instruction(result_instruction, &bin_op_instruction->base);
ConstExprValue *out_val = &result_instruction->value;

int err;
if ((err = ir_eval_math_op(resolved_type, op1_val, op_id, op2_val, out_val))) {
Expand All @@ -10789,7 +10789,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
return ira->codegen->builtin_types.entry_invalid;
}

ir_num_lit_fits_in_other_type(ira, &bin_op_instruction->base, resolved_type, false);
ir_num_lit_fits_in_other_type(ira, result_instruction, resolved_type, false);
return resolved_type;
}

Expand Down
25 changes: 25 additions & 0 deletions test/cases/eval.zig
Expand Up @@ -395,3 +395,28 @@ test "comptime slice of undefined pointer of length 0" {
const slice2 = (&i32)(undefined)[100..100];
assert(slice2.len == 0);
}

fn copyWithPartialInline(s: []u32, b: []u8) void {
comptime var i: usize = 0;
inline while (i < 4) : (i += 1) {
s[i] = 0;
s[i] |= u32(b[i*4+0]) << 24;
s[i] |= u32(b[i*4+1]) << 16;
s[i] |= u32(b[i*4+2]) << 8;
s[i] |= u32(b[i*4+3]) << 0;
}
}

test "binary math operator in partially inlined function" {
var s: [4]u32 = undefined;
var b: [16]u8 = undefined;

for (b) |*r, i|
*r = u8(i + 1);

copyWithPartialInline(s[0..], b[0..]);
assert(s[0] == 0x1020304);
assert(s[1] == 0x5060708);
assert(s[2] == 0x90a0b0c);
assert(s[3] == 0xd0e0f10);
}

0 comments on commit aaf2230

Please sign in to comment.