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)"""