astgen: fix defer RL annotation, compile_error noreturn, block force_comptime
Three bugs found by auditing against upstream AstGen.zig/AstRlAnnotate.zig: 1. rlExpr: defer was recursing into nd.rhs (always 0) instead of nd.lhs (the actual deferred expression), so the RL annotation pass never visited defer bodies. 2. addEnsureResult: compile_error was missing from the noreturn instruction list, causing spurious ensure_result_used instructions to be emitted after @compileError calls. 3. blockExprExpr: force_comptime was derived from gz->is_comptime, but upstream blockExpr always passes force_comptime=false to labeledBlockExpr. This caused labeled blocks in comptime contexts to incorrectly emit BLOCK_COMPTIME + BREAK_INLINE instead of BLOCK + BREAK. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
38
astgen.c
38
astgen.c
@@ -4762,7 +4762,7 @@ static uint32_t blockExprExpr(
|
||||
}
|
||||
|
||||
// Labeled block (AstGen.zig:2466-2536).
|
||||
bool force_comptime = gz->is_comptime;
|
||||
// Note: upstream blockExpr always passes force_comptime=false.
|
||||
uint32_t label_token = lbrace - 2;
|
||||
|
||||
// Compute break result info (AstGen.zig:2484-2492).
|
||||
@@ -4771,15 +4771,10 @@ static uint32_t blockExprExpr(
|
||||
bool need_result_rvalue = (break_ri.tag != rl.tag);
|
||||
|
||||
// Reserve the block instruction (AstGen.zig:2500-2501).
|
||||
ZirInstTag block_tag
|
||||
= force_comptime ? ZIR_INST_BLOCK_COMPTIME : ZIR_INST_BLOCK;
|
||||
uint32_t block_inst = makeBlockInst(ag, block_tag, gz, node);
|
||||
uint32_t block_inst = makeBlockInst(ag, ZIR_INST_BLOCK, gz, node);
|
||||
gzAppendInstruction(gz, block_inst);
|
||||
|
||||
GenZir block_scope = makeSubBlock(gz, scope);
|
||||
block_scope.is_inline = force_comptime; // AstGen.zig:2503
|
||||
if (force_comptime)
|
||||
block_scope.is_comptime = true;
|
||||
// Set label on block_scope (AstGen.zig:2504-2508).
|
||||
block_scope.label_token = label_token;
|
||||
block_scope.label_block_inst = block_inst;
|
||||
@@ -4790,29 +4785,19 @@ static uint32_t blockExprExpr(
|
||||
|
||||
if (!endsWithNoReturn(&block_scope)) {
|
||||
// Emit restore_err_ret_index (AstGen.zig:2515).
|
||||
if (!force_comptime) {
|
||||
ZirInstData rdata;
|
||||
rdata.un_node.operand = block_inst + ZIR_REF_START_INDEX;
|
||||
rdata.un_node.src_node
|
||||
= (int32_t)node - (int32_t)gz->decl_node_index;
|
||||
addInstruction(
|
||||
gz, ZIR_INST_RESTORE_ERR_RET_INDEX_UNCONDITIONAL, rdata);
|
||||
}
|
||||
ZirInstData rdata;
|
||||
rdata.un_node.operand = block_inst + ZIR_REF_START_INDEX;
|
||||
rdata.un_node.src_node = (int32_t)node - (int32_t)gz->decl_node_index;
|
||||
addInstruction(
|
||||
gz, ZIR_INST_RESTORE_ERR_RET_INDEX_UNCONDITIONAL, rdata);
|
||||
// rvalue + break (AstGen.zig:2516-2518).
|
||||
uint32_t result = rvalue(
|
||||
gz, block_scope.break_result_info, ZIR_REF_VOID_VALUE, node);
|
||||
ZirInstTag break_tag
|
||||
= force_comptime ? ZIR_INST_BREAK_INLINE : ZIR_INST_BREAK;
|
||||
addBreak(
|
||||
&block_scope, break_tag, block_inst, result, AST_NODE_OFFSET_NONE);
|
||||
addBreak(&block_scope, ZIR_INST_BREAK, block_inst, result,
|
||||
AST_NODE_OFFSET_NONE);
|
||||
}
|
||||
|
||||
if (force_comptime) {
|
||||
setBlockComptimeBody(
|
||||
ag, &block_scope, block_inst, COMPTIME_REASON_COMPTIME_KEYWORD);
|
||||
} else {
|
||||
setBlockBody(ag, &block_scope, block_inst);
|
||||
}
|
||||
setBlockBody(ag, &block_scope, block_inst);
|
||||
|
||||
// AstGen.zig:2531-2534.
|
||||
if (need_result_rvalue)
|
||||
@@ -6602,6 +6587,7 @@ static bool addEnsureResult(
|
||||
case ZIR_INST_TRAP:
|
||||
case ZIR_INST_CHECK_COMPTIME_CONTROL_FLOW:
|
||||
case ZIR_INST_SWITCH_CONTINUE:
|
||||
case ZIR_INST_COMPILE_ERROR:
|
||||
is_noreturn = true;
|
||||
elide_check = true;
|
||||
break;
|
||||
@@ -9577,7 +9563,7 @@ static bool rlExpr(
|
||||
|
||||
// defer (AstRlAnnotate.zig:148-151).
|
||||
case AST_NODE_DEFER:
|
||||
(void)rlExpr(ag, nd.rhs, block, RL_RI_NONE);
|
||||
(void)rlExpr(ag, nd.lhs, block, RL_RI_NONE);
|
||||
return false;
|
||||
|
||||
// container_field (AstRlAnnotate.zig:153-167).
|
||||
|
||||
Reference in New Issue
Block a user