Commit 3b40aaa01f
Changed files (3)
test
src/all_types.hpp
@@ -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 {
src/ir.cpp
@@ -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);
}
}
test/run_tests.cpp
@@ -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");
+
}
//////////////////////////////////////////////////////////////////////////////