diff --git a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp index b81b600..4a8c435 100644 --- a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp @@ -1300,6 +1300,36 @@ class StmtGenCifMixin: loop_unsigned = 1 break + # 3.7 stop 边界为负数字面量(-1 / -N)→ 撤回无符号谓词,必须用有符号比较。 + # 倒序循环条件为 i > stop;stop = -1 在无符号域里是 UINT_MAX,任何 i + # 都 ugt 不过它 → 条件恒假 → 循环体整段变死代码。TPC 的 for 条件只按 + # 循环变量注解定符号性(HandlesFor.py L218 `Gen._is_var_unsigned`), + # 未声明循环变量的 range(top - 1, -1, -1) 走有符号 sgt 可正常执行; + # 边界推导(上文 3.6)把「start 边界无符号」也算成无符号,覆盖了负步长的 + # SGT(即 step_neg_const 处注释里「修复 _find_provider 的 + # range(top-1,-1,-1) 循环体不执行」失效)→ _find_provider 恒返回 NULL + # → with 上下文的 __mbuddy__ 注入不上(FakeDuckTest Test 9 FAIL + + # 后续 _str.upper 解引用 NULL 崩溃)。负数字面量语义上属有符号域, + # 此处无条件退回有符号谓词(slt/sgt),与 3.6 的无符号优化不冲突。 + stop_neg_const: int = 0 + if arg_count >= 2: + stop_arg_node: ast.AST | t.CPtr = args.get(1) + if stop_arg_node is not None: + stn_k: int = stop_arg_node.kind() + if stn_k == ast.ASTKind.UnaryOp: + stop_uop: ast.UnaryOp | t.CPtr = (ast.UnaryOp | t.CPtr)(stop_arg_node) + if stop_uop.op == ast.OpKind.USub and stop_uop.operand is not None: + if stop_uop.operand.kind() == ast.ASTKind.Constant: + stop_uc: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(stop_uop.operand) + if stop_uc.int_val > 0: + stop_neg_const = 1 + elif stn_k == ast.ASTKind.Constant: + stop_c: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(stop_arg_node) + if stop_c.int_val < 0: + stop_neg_const = 1 + if stop_neg_const != 0: + loop_unsigned = 0 + # 4. 创建/查找循环变量 alloca # 必须用 lookup_current(仅当前作用域):闭包内 lookup_var 会跨函数 # 命中父函数同名变量(如父函数自己的循环计数器 i)→ 循环计数写到