| ... | @@ -147,7 +147,7 @@ pub fn analyzeBody( | ... | @@ -147,7 +147,7 @@ pub fn analyzeBody( |
| 147 | // directly jump to the next one, rather than detouring through the loop | 147 | // directly jump to the next one, rather than detouring through the loop |
| 148 | // continue expression. Related: https://github.com/ziglang/zig/issues/8220 | 148 | // continue expression. Related: https://github.com/ziglang/zig/issues/8220 |
| 149 | var i: usize = 0; | 149 | var i: usize = 0; |
| 150 | while (true) : (i += 1) { | 150 | while (true) { |
| 151 | const inst = body[i]; | 151 | const inst = body[i]; |
| 152 | const air_inst = switch (tags[inst]) { | 152 | const air_inst = switch (tags[inst]) { |
| 153 | // zig fmt: off | 153 | // zig fmt: off |
| ... | @@ -394,78 +394,97 @@ pub fn analyzeBody( | ... | @@ -394,78 +394,97 @@ pub fn analyzeBody( |
| 394 | // putting them into the map. | 394 | // putting them into the map. |
| 395 | .breakpoint => { | 395 | .breakpoint => { |
| 396 | try sema.zirBreakpoint(block, inst); | 396 | try sema.zirBreakpoint(block, inst); |
| | 397 | i += 1; |
| 397 | continue; | 398 | continue; |
| 398 | }, | 399 | }, |
| 399 | .fence => { | 400 | .fence => { |
| 400 | try sema.zirFence(block, inst); | 401 | try sema.zirFence(block, inst); |
| | 402 | i += 1; |
| 401 | continue; | 403 | continue; |
| 402 | }, | 404 | }, |
| 403 | .dbg_stmt => { | 405 | .dbg_stmt => { |
| 404 | try sema.zirDbgStmt(block, inst); | 406 | try sema.zirDbgStmt(block, inst); |
| | 407 | i += 1; |
| 405 | continue; | 408 | continue; |
| 406 | }, | 409 | }, |
| 407 | .ensure_err_payload_void => { | 410 | .ensure_err_payload_void => { |
| 408 | try sema.zirEnsureErrPayloadVoid(block, inst); | 411 | try sema.zirEnsureErrPayloadVoid(block, inst); |
| | 412 | i += 1; |
| 409 | continue; | 413 | continue; |
| 410 | }, | 414 | }, |
| 411 | .ensure_result_non_error => { | 415 | .ensure_result_non_error => { |
| 412 | try sema.zirEnsureResultNonError(block, inst); | 416 | try sema.zirEnsureResultNonError(block, inst); |
| | 417 | i += 1; |
| 413 | continue; | 418 | continue; |
| 414 | }, | 419 | }, |
| 415 | .ensure_result_used => { | 420 | .ensure_result_used => { |
| 416 | try sema.zirEnsureResultUsed(block, inst); | 421 | try sema.zirEnsureResultUsed(block, inst); |
| | 422 | i += 1; |
| 417 | continue; | 423 | continue; |
| 418 | }, | 424 | }, |
| 419 | .set_eval_branch_quota => { | 425 | .set_eval_branch_quota => { |
| 420 | try sema.zirSetEvalBranchQuota(block, inst); | 426 | try sema.zirSetEvalBranchQuota(block, inst); |
| | 427 | i += 1; |
| 421 | continue; | 428 | continue; |
| 422 | }, | 429 | }, |
| 423 | .store => { | 430 | .store => { |
| 424 | try sema.zirStore(block, inst); | 431 | try sema.zirStore(block, inst); |
| | 432 | i += 1; |
| 425 | continue; | 433 | continue; |
| 426 | }, | 434 | }, |
| 427 | .store_node => { | 435 | .store_node => { |
| 428 | try sema.zirStoreNode(block, inst); | 436 | try sema.zirStoreNode(block, inst); |
| | 437 | i += 1; |
| 429 | continue; | 438 | continue; |
| 430 | }, | 439 | }, |
| 431 | .store_to_block_ptr => { | 440 | .store_to_block_ptr => { |
| 432 | try sema.zirStoreToBlockPtr(block, inst); | 441 | try sema.zirStoreToBlockPtr(block, inst); |
| | 442 | i += 1; |
| 433 | continue; | 443 | continue; |
| 434 | }, | 444 | }, |
| 435 | .store_to_inferred_ptr => { | 445 | .store_to_inferred_ptr => { |
| 436 | try sema.zirStoreToInferredPtr(block, inst); | 446 | try sema.zirStoreToInferredPtr(block, inst); |
| | 447 | i += 1; |
| 437 | continue; | 448 | continue; |
| 438 | }, | 449 | }, |
| 439 | .resolve_inferred_alloc => { | 450 | .resolve_inferred_alloc => { |
| 440 | try sema.zirResolveInferredAlloc(block, inst); | 451 | try sema.zirResolveInferredAlloc(block, inst); |
| | 452 | i += 1; |
| 441 | continue; | 453 | continue; |
| 442 | }, | 454 | }, |
| 443 | .validate_struct_init_ptr => { | 455 | .validate_struct_init_ptr => { |
| 444 | try sema.zirValidateStructInitPtr(block, inst); | 456 | try sema.zirValidateStructInitPtr(block, inst); |
| | 457 | i += 1; |
| 445 | continue; | 458 | continue; |
| 446 | }, | 459 | }, |
| 447 | .validate_array_init_ptr => { | 460 | .validate_array_init_ptr => { |
| 448 | try sema.zirValidateArrayInitPtr(block, inst); | 461 | try sema.zirValidateArrayInitPtr(block, inst); |
| | 462 | i += 1; |
| 449 | continue; | 463 | continue; |
| 450 | }, | 464 | }, |
| 451 | .@"export" => { | 465 | .@"export" => { |
| 452 | try sema.zirExport(block, inst); | 466 | try sema.zirExport(block, inst); |
| | 467 | i += 1; |
| 453 | continue; | 468 | continue; |
| 454 | }, | 469 | }, |
| 455 | .set_align_stack => { | 470 | .set_align_stack => { |
| 456 | try sema.zirSetAlignStack(block, inst); | 471 | try sema.zirSetAlignStack(block, inst); |
| | 472 | i += 1; |
| 457 | continue; | 473 | continue; |
| 458 | }, | 474 | }, |
| 459 | .set_cold => { | 475 | .set_cold => { |
| 460 | try sema.zirSetAlignStack(block, inst); | 476 | try sema.zirSetAlignStack(block, inst); |
| | 477 | i += 1; |
| 461 | continue; | 478 | continue; |
| 462 | }, | 479 | }, |
| 463 | .set_float_mode => { | 480 | .set_float_mode => { |
| 464 | try sema.zirSetFloatMode(block, inst); | 481 | try sema.zirSetFloatMode(block, inst); |
| | 482 | i += 1; |
| 465 | continue; | 483 | continue; |
| 466 | }, | 484 | }, |
| 467 | .set_runtime_safety => { | 485 | .set_runtime_safety => { |
| 468 | try sema.zirSetRuntimeSafety(block, inst); | 486 | try sema.zirSetRuntimeSafety(block, inst); |
| | 487 | i += 1; |
| 469 | continue; | 488 | continue; |
| 470 | }, | 489 | }, |
| 471 | | 490 | |
| ... | @@ -509,7 +528,8 @@ pub fn analyzeBody( | ... | @@ -509,7 +528,8 @@ pub fn analyzeBody( |
| 509 | }; | 528 | }; |
| 510 | if (air_inst.ty.isNoReturn()) | 529 | if (air_inst.ty.isNoReturn()) |
| 511 | return always_noreturn; | 530 | return always_noreturn; |
| 512 | try map.putNoClobber(sema.gpa, inst, air_inst); | 531 | try map.put(sema.gpa, inst, air_inst); |
| | 532 | i += 1; |
| 513 | } | 533 | } |
| 514 | } | 534 | } |
| 515 | | 535 | |
| ... | @@ -1238,9 +1258,26 @@ fn zirAllocExtended( | ... | @@ -1238,9 +1258,26 @@ fn zirAllocExtended( |
| 1238 | } | 1258 | } |
| 1239 | | 1259 | |
| 1240 | fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { | 1260 | fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { |
| | 1261 | const tracy = trace(@src()); |
| | 1262 | defer tracy.end(); |
| | 1263 | |
| 1241 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 1264 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 1242 | const src = inst_data.src(); | 1265 | const src = inst_data.src(); |
| 1243 | return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocComptime", .{}); | 1266 | const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node }; |
| | 1267 | const var_type = try sema.resolveType(block, ty_src, inst_data.operand); |
| | 1268 | const ptr_type = try sema.mod.simplePtrType(sema.arena, var_type, true, .One); |
| | 1269 | |
| | 1270 | const val_payload = try sema.arena.create(Value.Payload.ComptimeAlloc); |
| | 1271 | val_payload.* = .{ |
| | 1272 | .data = .{ |
| | 1273 | .runtime_index = block.runtime_index, |
| | 1274 | .val = undefined, // astgen guarantees there will be a store before the first load |
| | 1275 | }, |
| | 1276 | }; |
| | 1277 | return sema.mod.constInst(sema.arena, src, .{ |
| | 1278 | .ty = ptr_type, |
| | 1279 | .val = Value.initPayload(&val_payload.base), |
| | 1280 | }); |
| 1244 | } | 1281 | } |
| 1245 | | 1282 | |
| 1246 | fn zirAllocInferredComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { | 1283 | fn zirAllocInferredComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { |
| ... | @@ -1742,6 +1779,9 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) InnerE | ... | @@ -1742,6 +1779,9 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) InnerE |
| 1742 | }; | 1779 | }; |
| 1743 | var child_block = parent_block.makeSubBlock(); | 1780 | var child_block = parent_block.makeSubBlock(); |
| 1744 | child_block.label = &label; | 1781 | child_block.label = &label; |
| | 1782 | child_block.runtime_cond = null; |
| | 1783 | child_block.runtime_loop = src; |
| | 1784 | child_block.runtime_index += 1; |
| 1745 | const merges = &child_block.label.?.merges; | 1785 | const merges = &child_block.label.?.merges; |
| 1746 | | 1786 | |
| 1747 | defer child_block.instructions.deinit(sema.gpa); | 1787 | defer child_block.instructions.deinit(sema.gpa); |
| ... | @@ -4066,6 +4106,9 @@ fn analyzeSwitch( | ... | @@ -4066,6 +4106,9 @@ fn analyzeSwitch( |
| 4066 | const cases = try sema.arena.alloc(Inst.SwitchBr.Case, scalar_cases_len); | 4106 | const cases = try sema.arena.alloc(Inst.SwitchBr.Case, scalar_cases_len); |
| 4067 | | 4107 | |
| 4068 | var case_block = child_block.makeSubBlock(); | 4108 | var case_block = child_block.makeSubBlock(); |
| | 4109 | case_block.runtime_loop = null; |
| | 4110 | case_block.runtime_cond = operand.src; |
| | 4111 | case_block.runtime_index += 1; |
| 4069 | defer case_block.instructions.deinit(gpa); | 4112 | defer case_block.instructions.deinit(gpa); |
| 4070 | | 4113 | |
| 4071 | var extra_index: usize = special.end; | 4114 | var extra_index: usize = special.end; |
| ... | @@ -4584,14 +4627,14 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr | ... | @@ -4584,14 +4627,14 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr |
| 4584 | | 4627 | |
| 4585 | const tag_override = block.sema.code.instructions.items(.tag)[inst]; | 4628 | const tag_override = block.sema.code.instructions.items(.tag)[inst]; |
| 4586 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 4629 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 4587 | const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; | 4630 | sema.src = .{ .node_offset_bin_op = inst_data.src_node }; |
| 4588 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; | 4631 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 4589 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; | 4632 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 4590 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 4633 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 4591 | const lhs = try sema.resolveInst(extra.lhs); | 4634 | const lhs = try sema.resolveInst(extra.lhs); |
| 4592 | const rhs = try sema.resolveInst(extra.rhs); | 4635 | const rhs = try sema.resolveInst(extra.rhs); |
| 4593 | | 4636 | |
| 4594 | return sema.analyzeArithmetic(block, tag_override, lhs, rhs, src, lhs_src, rhs_src); | 4637 | return sema.analyzeArithmetic(block, tag_override, lhs, rhs, sema.src, lhs_src, rhs_src); |
| 4595 | } | 4638 | } |
| 4596 | | 4639 | |
| 4597 | fn zirOverflowArithmetic( | 4640 | fn zirOverflowArithmetic( |
| ... | @@ -5150,6 +5193,9 @@ fn zirBoolBr( | ... | @@ -5150,6 +5193,9 @@ fn zirBoolBr( |
| 5150 | }; | 5193 | }; |
| 5151 | | 5194 | |
| 5152 | var child_block = parent_block.makeSubBlock(); | 5195 | var child_block = parent_block.makeSubBlock(); |
| | 5196 | child_block.runtime_loop = null; |
| | 5197 | child_block.runtime_cond = lhs.src; |
| | 5198 | child_block.runtime_index += 1; |
| 5153 | defer child_block.instructions.deinit(sema.gpa); | 5199 | defer child_block.instructions.deinit(sema.gpa); |
| 5154 | | 5200 | |
| 5155 | var then_block = child_block.makeSubBlock(); | 5201 | var then_block = child_block.makeSubBlock(); |
| ... | @@ -5258,6 +5304,9 @@ fn zirCondbr( | ... | @@ -5258,6 +5304,9 @@ fn zirCondbr( |
| 5258 | } | 5304 | } |
| 5259 | | 5305 | |
| 5260 | var sub_block = parent_block.makeSubBlock(); | 5306 | var sub_block = parent_block.makeSubBlock(); |
| | 5307 | sub_block.runtime_loop = null; |
| | 5308 | sub_block.runtime_cond = cond.src; |
| | 5309 | sub_block.runtime_index += 1; |
| 5261 | defer sub_block.instructions.deinit(sema.gpa); | 5310 | defer sub_block.instructions.deinit(sema.gpa); |
| 5262 | | 5311 | |
| 5263 | _ = try sema.analyzeBody(&sub_block, then_body); | 5312 | _ = try sema.analyzeBody(&sub_block, then_body); |
| ... | @@ -6753,7 +6802,35 @@ fn storePtr( | ... | @@ -6753,7 +6802,35 @@ fn storePtr( |
| 6753 | if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null) | 6802 | if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null) |
| 6754 | return; | 6803 | return; |
| 6755 | | 6804 | |
| 6756 | // TODO handle comptime pointer writes | 6805 | if (try sema.resolvePossiblyUndefinedValue(block, src, ptr)) |ptr_val| { |
| | 6806 | const const_val = (try sema.resolvePossiblyUndefinedValue(block, src, value)) orelse |
| | 6807 | return sema.mod.fail(&block.base, src, "cannot store runtime value in compile time variable", .{}); |
| | 6808 | |
| | 6809 | const comptime_alloc = ptr_val.castTag(.comptime_alloc).?; |
| | 6810 | if (comptime_alloc.data.runtime_index < block.runtime_index) { |
| | 6811 | if (block.runtime_cond) |cond_src| { |
| | 6812 | const msg = msg: { |
| | 6813 | const msg = try sema.mod.errMsg(&block.base, src, "store to comptime variable depends on runtime condition", .{}); |
| | 6814 | errdefer msg.destroy(sema.gpa); |
| | 6815 | try sema.mod.errNote(&block.base, cond_src, msg, "runtime condition here", .{}); |
| | 6816 | break :msg msg; |
| | 6817 | }; |
| | 6818 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); |
| | 6819 | } |
| | 6820 | if (block.runtime_loop) |loop_src| { |
| | 6821 | const msg = msg: { |
| | 6822 | const msg = try sema.mod.errMsg(&block.base, src, "cannot store to comptime variable in non-inline loop", .{}); |
| | 6823 | errdefer msg.destroy(sema.gpa); |
| | 6824 | try sema.mod.errNote(&block.base, loop_src, msg, "non-inline loop here", .{}); |
| | 6825 | break :msg msg; |
| | 6826 | }; |
| | 6827 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); |
| | 6828 | } |
| | 6829 | unreachable; |
| | 6830 | } |
| | 6831 | comptime_alloc.data.val = const_val; |
| | 6832 | return; |
| | 6833 | } |
| 6757 | // TODO handle if the element type requires comptime | 6834 | // TODO handle if the element type requires comptime |
| 6758 | | 6835 | |
| 6759 | try sema.requireRuntimeBlock(block, src); | 6836 | try sema.requireRuntimeBlock(block, src); |