add compile error for control flow using comptime var at runtime

closes #266
This commit is contained in:
Andrew Kelley 2017-02-24 13:57:00 -05:00
parent 4b99f5978f
commit 3b40aaa01f
3 changed files with 29 additions and 0 deletions

View File

@ -1589,6 +1589,10 @@ struct IrBasicBlock {
// analyze the basic block. If the same instruction wants us to emit
// the same basic block, then we re-generate it instead of saving it.
IrInstruction *ref_instruction;
// When this is non-null, a branch to this basic block is only allowed
// if the branch is comptime. The instruction points to the reason
// the basic block must be comptime.
IrInstruction *must_be_comptime_source_instr;
};
enum IrInstructionId {

View File

@ -8601,6 +8601,15 @@ static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr
return ir_inline_bb(ira, &br_instruction->base, old_dest_block);
IrBasicBlock *new_bb = ir_get_new_bb(ira, old_dest_block, &br_instruction->base);
if (new_bb->must_be_comptime_source_instr) {
ErrorMsg *msg = ir_add_error(ira, &br_instruction->base,
buf_sprintf("control flow attempts to use compile-time variable at runtime"));
add_error_note(ira->codegen, msg, new_bb->must_be_comptime_source_instr->source_node,
buf_sprintf("compile-time variable assigned here"));
return ir_unreach_error(ira);
}
ir_build_br_from(&ira->new_irb, &br_instruction->base, new_bb);
return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
}
@ -9392,6 +9401,9 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru
ConstExprValue *dest_val = const_ptr_pointee(&ptr->value);
if (dest_val->special != ConstValSpecialRuntime) {
*dest_val = casted_value->value;
if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) {
ira->new_irb.current_basic_block->must_be_comptime_source_instr = &store_ptr_instruction->base;
}
return ir_analyze_void(ira, &store_ptr_instruction->base);
}
}

View File

@ -1678,6 +1678,19 @@ fn assert(ok: bool) {
".tmp_source.zig:11:14: error: unable to evaluate constant expression",
".tmp_source.zig:7:20: note: called from here");
add_compile_fail_case("control flow uses comptime var at runtime", R"SOURCE(
fn foo() {
comptime var i = 0;
while (i < 5; i += 1) {
bar();
}
}
fn bar() { }
)SOURCE", 2,
".tmp_source.zig:4:5: error: control flow attempts to use compile-time variable at runtime",
".tmp_source.zig:4:21: note: compile-time variable assigned here");
}
//////////////////////////////////////////////////////////////////////////////