fix: for循环变量作用域 + 列表推导crash (两个已知bug)

Bug 1 - For循环变量作用域:
- AST_BLOCK 在 sema 中未创建子作用域 → 连续 for 循环用同名变量报"重复定义"
- 修复: sema AST_BLOCK 创建 block_scope (scope_new)
- 修复: codegen AST_BLOCK 保存/恢复 var_table 实现块级变量隔离

Bug 2 - 列表推导 >2元素 crash:
- sema 对 TYPE_ARRAY 标注跳过 init 分析 → 列表推导表达式未被semantize
- 导致 codegen 处 element_type=0, array_size=0 → LLVM alloca 崩溃
- 修复: 仅自引用 (= 变量名) 跳过分析,列表推导等正常分析
- 修复: cg_list_comp 使用 to_llvm_type(elem) 而非 type_info_to_llvm(full_array)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 18:03:25 +08:00
parent f5c0650a97
commit 6d5f8092a7
3 changed files with 15 additions and 6 deletions
+3 -1
View File
@@ -205,10 +205,12 @@ void codegen_stmt(CgCtx* ctx, AstNode* node) {
case AST_BLOCK: {
if (++codegen_depth > MAX_CODEGEN_DEPTH) { codegen_depth--; return; }
size_t block_mark = ctx->cleanup_count;
VarEntry* saved_table = ctx->var_table;
for (size_t i = 0; i < node->as.block.stmt_count; i++) {
codegen_stmt(ctx, node->as.block.stmts[i]);
}
cleanup_emit(ctx, block_mark); // 作用域退出: 释放块内 str 堆分配
ctx->var_table = saved_table;
cleanup_emit(ctx, block_mark);
codegen_depth--;
break;
}