authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-03 21:24:20-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-03 21:24:20-04:00
loge82cd53df483aa08354de935879a0f9935ba4a1b
tree67f249e4ac3728682975a97af5cbc47d3eb4b6f0
parenta11e73bee2266d4c568bdf9b23c891ac1365bb09
signaturelock-open Commit is signed but in an unrecognized format.

fix incorrect value for inline loop

09cc1dc66067f378 failed to handle mem_slot_index correctly closes #1436

2 files changed, 28 insertions(+), 11 deletions(-)

src/ir.cpp+19-11
...@@ -17,8 +17,7 @@...@@ -17,8 +17,7 @@
17#include "util.hpp"17#include "util.hpp"
1818
19struct IrExecContext {19struct IrExecContext {
20 ConstExprValue *mem_slot_list;20 ZigList<ConstExprValue *> mem_slot_list;
21 size_t mem_slot_count;
22};21};
2322
24struct IrBuilder {23struct IrBuilder {
...@@ -12496,13 +12495,20 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -12496,13 +12495,20 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
12496 }12495 }
12497 }12496 }
1249812497
12499 if (var->value->type != nullptr && var->value->type != result_type && !is_comptime_var) {12498 if (var->value->type != nullptr && !is_comptime_var) {
12500 // This is at least the second time we've seen this variable declaration during analysis.12499 // This is at least the second time we've seen this variable declaration during analysis.
12501 // This means that this is actually a different variable due to, e.g. an inline while loop.12500 // This means that this is actually a different variable due to, e.g. an inline while loop.
12502 // We make a new variable so that it can hold a different type, and so the debug info can12501 // We make a new variable so that it can hold a different type, and so the debug info can
12503 // be distinct.12502 // be distinct.
12504 VariableTableEntry *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope,12503 VariableTableEntry *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope,
12505 &var->name, var->src_is_const, var->gen_is_const, var->shadowable, var->is_comptime, true);12504 &var->name, var->src_is_const, var->gen_is_const, var->shadowable, var->is_comptime, true);
12505 new_var->owner_exec = var->owner_exec;
12506 if (var->mem_slot_index != SIZE_MAX) {
12507 ConstExprValue *vals = create_const_vals(1);
12508 new_var->mem_slot_index = ira->exec_context.mem_slot_list.length;
12509 ira->exec_context.mem_slot_list.append(vals);
12510 }
12511
12506 var->next_var = new_var;12512 var->next_var = new_var;
12507 var = new_var;12513 var = new_var;
12508 }12514 }
...@@ -12525,10 +12531,9 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -12525,10 +12531,9 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
1252512531
12526 if (casted_init_value->value.special != ConstValSpecialRuntime) {12532 if (casted_init_value->value.special != ConstValSpecialRuntime) {
12527 if (var->mem_slot_index != SIZE_MAX) {12533 if (var->mem_slot_index != SIZE_MAX) {
12528 assert(var->mem_slot_index < ira->exec_context.mem_slot_count);12534 assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length);
12529 ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];12535 ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index);
12530 copy_const_val(mem_slot, &casted_init_value->value,12536 copy_const_val(mem_slot, &casted_init_value->value, !is_comptime_var || var->gen_is_const);
12531 !is_comptime_var || var->gen_is_const);
1253212537
12533 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) {12538 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) {
12534 ir_build_const_from(ira, &decl_var_instruction->base);12539 ir_build_const_from(ira, &decl_var_instruction->base);
...@@ -13012,8 +13017,8 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,...@@ -13012,8 +13017,8 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
13012 assert(var->owner_exec != nullptr);13017 assert(var->owner_exec != nullptr);
13013 assert(var->owner_exec->analysis != nullptr);13018 assert(var->owner_exec->analysis != nullptr);
13014 IrExecContext *exec_context = &var->owner_exec->analysis->exec_context;13019 IrExecContext *exec_context = &var->owner_exec->analysis->exec_context;
13015 assert(var->mem_slot_index < exec_context->mem_slot_count);13020 assert(var->mem_slot_index < exec_context->mem_slot_list.length);
13016 mem_slot = &exec_context->mem_slot_list[var->mem_slot_index];13021 mem_slot = exec_context->mem_slot_list.at(var->mem_slot_index);
13017 }13022 }
13018 }13023 }
1301913024
...@@ -21228,8 +21233,11 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl...@@ -21228,8 +21233,11 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl
21228 ira->new_irb.codegen = codegen;21233 ira->new_irb.codegen = codegen;
21229 ira->new_irb.exec = new_exec;21234 ira->new_irb.exec = new_exec;
2123021235
21231 ira->exec_context.mem_slot_count = ira->old_irb.exec->mem_slot_count;21236 ConstExprValue *vals = create_const_vals(ira->old_irb.exec->mem_slot_count);
21232 ira->exec_context.mem_slot_list = create_const_vals(ira->exec_context.mem_slot_count);21237 ira->exec_context.mem_slot_list.resize(ira->old_irb.exec->mem_slot_count);
21238 for (size_t i = 0; i < ira->exec_context.mem_slot_list.length; i += 1) {
21239 ira->exec_context.mem_slot_list.items[i] = &vals[i];
21240 }
2123321241
21234 IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0);21242 IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0);
21235 IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr);21243 IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr);
test/cases/eval.zig+9
...@@ -665,3 +665,12 @@ fn testVarInsideInlineLoop(args: ...) void {...@@ -665,3 +665,12 @@ fn testVarInsideInlineLoop(args: ...) void {
665 if (i == 1) assert(x == 42);665 if (i == 1) assert(x == 42);
666 }666 }
667}667}
668
669test "inline for with same type but different values" {
670 var res: usize = 0;
671 inline for ([]type{ [2]u8, [1]u8, [2]u8 }) |T| {
672 var a: T = undefined;
673 res += a.len;
674 }
675 assert(res == 5);
676}