From af5fba81c50c0e8a315b627bef0b9dae72ede67a Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 28 Sep 2026 19:40:42 +0800 Subject: [PATCH] =?UTF-8?q?fix(transpyv):=20=E4=B8=A5=E6=A0=BC=E6=8C=87?= =?UTF-8?q?=E9=92=88=E8=A7=84=E5=88=99=E4=B8=8B=E7=9A=84=E6=BA=90=E7=A0=81?= =?UTF-8?q?=E7=BA=A7=E7=AA=84=E5=8C=96=E4=B8=8E=E8=B7=A8=E5=B1=82=E6=8C=87?= =?UTF-8?q?=E9=92=88=E5=86=99=E6=B3=95=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit c 源码违规(按新严格指针规则的显式书写): 1) AssignGenMixin.vp 属性赋值:target 是基类 ast.AST*,而 CallGenProp._try_property_setter 形参是 ast.Attribute*。基类指针传派生类形参属 向下转型,严格指针规则下禁止 ⇒ 在 ASTKind 判据确定为 Attribute 后显式窄化 `at_tg: ast.Attribute* = ast.Attribute*(target)`,并复用到 fd_an(不再重复窄化)。 2) TypeGenResolve.vp `return (str | t.CPtr)(v)`:`(str | t.CPtr)` 语义是 i8**(char**), 而该函数声明返回 i8*,声明/返回层数不符 ⇒ 改为 `t.CPtr(v)`(i8* 显式转换)。 同文件另含仓库内既有书写统一(ast.OpKind.USub 全限定名、rawptr(...) 取代 (str | t.CPtr)(...)、空行/续行缩进整理),无行为变化。 --- App/lib/core/Gen/AssignGenMixin.vp | 14 +++--- App/lib/core/Gen/Type/TypeGenResolve.vp | 62 ++++++++++++------------- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index f6efeee..376353f 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -585,9 +585,7 @@ novirtual class AssignGenMixin: # UnaryOp(USub, Constant)),故只拦 CONST_FLOAT 这一种内层形态。 if val_node is not None and val_node.kind() == ast.ASTKind.UnaryOp: uu_cd: ast.UnaryOp* = ast.UnaryOp*(val_node) - if uu_cd is not None and uu_cd.op == OpKind.USub \ - and uu_cd.operand is not None \ - and uu_cd.operand.kind() == ast.ASTKind.Constant: + if uu_cd is not None and uu_cd.op == ast.OpKind.USub and uu_cd.operand is not None and uu_cd.operand.kind() == ast.ASTKind.Constant: ic_cd: ast.Constant* = ast.Constant*(uu_cd.operand) if ic_cd is not None and ic_cd.const_kind == ast.CONST_FLOAT: val_node = uu_cd.operand @@ -3034,16 +3032,20 @@ novirtual class AssignGenMixin: # Attribute 赋值: obj.field = val if tk == ast.ASTKind.Attribute: + # 目标类型已由上面的 ASTKind 判据确定为 Attribute ⇒ 在此显式窄化。 + # 必须窄化:_try_property_setter 的形参是 ast.Attribute*,而 target + # 是基类 ast.AST*;基类指针传派生类形参属向下转型,严格指针规则下禁止。 + at_tg: ast.Attribute* = ast.Attribute*(target) # property setter 拦截: obj.attr = v 且 attr 是 @x.setter 方法时, # 生成 call Class.attr$set(obj, v),跳过字段存储 # 注意参数顺序:_try_property_setter(pool, builder, mod, ...)。 - if self.Gen.CallGenProp._try_property_setter(pool, builder, mod, target, rhs_val, trans) == 1: + if self.Gen.CallGenProp._try_property_setter(pool, builder, mod, at_tg, rhs_val, trans) == 1: continue # FakeDuck: 影子结构体属性写入 (str 变量的 per-instance 字段) # a.__data__ = v → GEP {a}__meta__[field] 并 store # 对齐 TPC HandlesAssign.py L67-76:对象是 Name 变量且存在 # {var}__meta__ 影子(fd2 创建)时,属性写入改走影子结构体。 - fd_an: ast.Attribute* = ast.Attribute*(target) + fd_an: ast.Attribute* = at_tg if fd_an is not None and fd_an.value is not None and fd_an.attr is not None: if fd_an.value.kind() == ast.ASTKind.Name: fd_obj_nm: ast.Name* = ast.Name*(fd_an.value) @@ -3544,7 +3546,7 @@ novirtual class AssignGenMixin: mro_ptr: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi: int = 1 while mro_ptr is not None and mro_ptr[mi] != 0: - anc: str = (str | t.CPtr)(mro_ptr[mi]) + anc: str = rawptr(mro_ptr[mi]) if anc is not None: anc_lookup: str = pool.alloc(128) if anc_lookup is not None: diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index 1eead2f..32ab540 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -1218,7 +1218,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): stdlib.free(key_buf) if v is None: return None - return (str | t.CPtr)(v) + return t.CPtr(v) def _lookup_library_typedef(self, pool: memhub.MemBuddy*, mod: str, attr: str) -> str: """查库模块源文件中 "attr: t.CTypedef = TYPE" 并注册,返回 TYPE 或 None @@ -1365,36 +1365,36 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): or string.strstr(triple, "msvc") is not None: return llvmlite.Int32(pool) return llvmlite.Int64(pool) - # ============================================================ - # _IsCallableSubscriptValue - Subscript 的 value 是否为函数指针类型构造子 - # - # 两种书写形态逐点等价(同 i8*): - # t.Callable[...] / c.Callable[...] → Attribute(attr="Callable") - # callable[...] / Callable[...] → Name(内建别名,注解位置生效) - # 用于放行"空下标/空参数表"的无签名形态(slice=None / 空 List): - # t.Callable[] / t.Callable[[]] / callable[] / callable[[]] - # ============================================================ - def _IsCallableSubscriptValue(self, value_node: ast.AST*) -> int: - if value_node is None: - return 0 - vk: int = value_node.kind() - if vk == ast.ASTKind.Attribute: - at: ast.Attribute* = ast.Attribute*(value_node) - if at.attr is None: - return 0 - if string.strcmp(at.attr, "Callable") == 0: - return 1 - return 0 - if vk == ast.ASTKind.Name: - nm: ast.Name* = ast.Name*(value_node) - if nm.id is None: - return 0 - if string.strcmp(nm.id, "callable") == 0: - return 1 - if string.strcmp(nm.id, "Callable") == 0: - return 1 - return 0 - + # ============================================================ + # _IsCallableSubscriptValue - Subscript 的 value 是否为函数指针类型构造子 + # + # 两种书写形态逐点等价(同 i8*): + # t.Callable[...] / c.Callable[...] → Attribute(attr="Callable") + # callable[...] / Callable[...] → Name(内建别名,注解位置生效) + # 用于放行"空下标/空参数表"的无签名形态(slice=None / 空 List): + # t.Callable[] / t.Callable[[]] / callable[] / callable[[]] + # ============================================================ + def _IsCallableSubscriptValue(self, value_node: ast.AST*) -> int: + if value_node is None: + return 0 + vk: int = value_node.kind() + if vk == ast.ASTKind.Attribute: + at: ast.Attribute* = ast.Attribute*(value_node) + if at.attr is None: + return 0 + if string.strcmp(at.attr, "Callable") == 0: + return 1 + return 0 + if vk == ast.ASTKind.Name: + nm: ast.Name* = ast.Name*(value_node) + if nm.id is None: + return 0 + if string.strcmp(nm.id, "callable") == 0: + return 1 + if string.strcmp(nm.id, "Callable") == 0: + return 1 + return 0 + def map_t_type(self, pool: memhub.MemBuddy*, type_name: str) -> llvmlite.LLVMType*: """将 t.CXxx / c.CXxx 类型名映射到 LLVMType