From 8db2d1c23bccc8b7436b2ecfe129a32f85f10db6 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 18 Aug 2026 09:51:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(assign):=20=5Fis=5Fscalar=5Fty=5Fname=20?= =?UTF-8?q?=E6=94=B9=E7=99=BD=E5=90=8D=E5=8D=95=EF=BC=8C=E4=BF=AE=20list[s?= =?UTF-8?q?tr].get=20=E8=BF=94=E5=9B=9E=E7=B1=BB=E5=9E=8B=E4=B8=8D?= =?UTF-8?q?=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原实现排除 Ptr/str/bytes/| 后默认返回 1(标量),把未知类名(如泛型 上下文污染产生的 llvmlite.Value)误判为标量 → IsPtrElement=0 → elem_ptr[0] 走通用路径生成 Value*,list[str].get 声明 i8* 与 ret Value* 不匹配(8fbba llc 报错)。改白名单:已知整数/浮点/字符标量 才返回 1,未知类名按 8 字节指针槽(list 元素本就是 8 字节槽)。 --- App/lib/core/Gen/AssignGenMixin.vp | 50 ++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index a1948cf..ef56171 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -447,13 +447,18 @@ class AssignGenMixin: return 0 def _is_scalar_ty_name(self, ty_name: str) -> int: - """判断类型名是否为纯标量(不含指针标记),用于泛型 T 的联合元素类型判定 + """判断类型名是否为已知纯标量(整数/浮点/字符),白名单判定 泛型 T | t.CPtr(如 _list.vp 的 elem_ptr)经 Fix A(TypeGenMixin 联合 解析保留泛型标量)后 alloca 变 Ptr(标量):T 为纯标量(int/float/double/ i64 等)时下标按标量自身大小步长,不能再按 8 字节指针槽——否则 Ptr(标量) alloca + IsPtrElement 路径(load 标量当指针)产生非法 IR。 指针/联合/str/bytes 才保持 8 字节指针槽语义。 + + 原实现"排除 Ptr/str/bytes/| 后默认返回 1"把**未知类名**(如泛型上下文 + 污染产生的 llvmlite.Value)误判为标量 → IsPtrElement=0 → elem_ptr[0] + 走通用路径生成 Value* → list[str].get 声明 i8* 与 ret Value* 不匹配 + (8fbba llc 报错根因)。改白名单:已知标量才 1,未知类名按 8 字节指针槽。 """ if ty_name is None: return 0 @@ -471,7 +476,48 @@ class AssignGenMixin: return 0 if string.strstr(ty_name, "Ptr") is not None: return 0 - return 1 + # === 白名单:已知纯标量(基础名 + stdint 大写别名) === + if string.strcmp(ty_name, "int") == 0: return 1 + if string.strcmp(ty_name, "CInt") == 0: return 1 + if string.strcmp(ty_name, "CChar") == 0: return 1 + if string.strcmp(ty_name, "CUnsignedChar") == 0: return 1 + if string.strcmp(ty_name, "CShort") == 0: return 1 + if string.strcmp(ty_name, "CUnsignedShort") == 0: return 1 + if string.strcmp(ty_name, "CLong") == 0: return 1 + if string.strcmp(ty_name, "CUnsignedLong") == 0: return 1 + if string.strcmp(ty_name, "CLongLong") == 0: return 1 + if string.strcmp(ty_name, "CUnsignedLongLong") == 0: return 1 + if string.strcmp(ty_name, "CSizeT") == 0: return 1 + if string.strcmp(ty_name, "BOOL") == 0: return 1 + if string.strcmp(ty_name, "BYTE") == 0: return 1 + if string.strcmp(ty_name, "UCHAR") == 0: return 1 + if string.strcmp(ty_name, "CHAR") == 0: return 1 + if string.strcmp(ty_name, "SHORT") == 0: return 1 + if string.strcmp(ty_name, "USHORT") == 0: return 1 + if string.strcmp(ty_name, "LONG") == 0: return 1 + if string.strcmp(ty_name, "ULONG") == 0: return 1 + if string.strcmp(ty_name, "LONGLONG") == 0: return 1 + if string.strcmp(ty_name, "ULONGLONG") == 0: return 1 + if string.strcmp(ty_name, "INT") == 0: return 1 + if string.strcmp(ty_name, "UINT") == 0: return 1 + if string.strcmp(ty_name, "WORD") == 0: return 1 + if string.strcmp(ty_name, "DWORD") == 0: return 1 + if string.strcmp(ty_name, "QWORD") == 0: return 1 + # 定长整数/浮点(C*T 形式与裸别名,strstr 前缀匹配) + if string.strstr(ty_name, "Int8") is not None: return 1 + if string.strstr(ty_name, "Int16") is not None: return 1 + if string.strstr(ty_name, "Int32") is not None: return 1 + if string.strstr(ty_name, "Int64") is not None: return 1 + if string.strstr(ty_name, "UInt8") is not None: return 1 + if string.strstr(ty_name, "UInt16") is not None: return 1 + if string.strstr(ty_name, "UInt32") is not None: return 1 + if string.strstr(ty_name, "UInt64") is not None: return 1 + if string.strstr(ty_name, "Float") is not None: return 1 + if string.strstr(ty_name, "FLOAT") is not None: return 1 + if string.strstr(ty_name, "Double") is not None: return 1 + if string.strstr(ty_name, "DOUBLE") is not None: return 1 + # 未知类名(结构体/类/污染类型)→ 非标量,按 8 字节指针槽 + return 0 def _is_generic_tp_or_nested(self, node: ast.AST | t.CPtr) -> int: """判断注解节点是否为泛型类型参数名(单字母大写,如 T)或嵌套联合(BinOp)"""