fix(assign): _is_scalar_ty_name 改白名单,修 list[str].get 返回类型不匹配

原实现排除 Ptr/str/bytes/| 后默认返回 1(标量),把未知类名(如泛型
上下文污染产生的 llvmlite.Value)误判为标量 → IsPtrElement=0 →
elem_ptr[0] 走通用路径生成 Value*,list[str].get 声明 i8* 与 ret
Value* 不匹配(8fbba llc 报错)。改白名单:已知整数/浮点/字符标量
才返回 1,未知类名按 8 字节指针槽(list 元素本就是 8 字节槽)。
This commit is contained in:
TermiNexus committed 2026-08-18 09:51:54 +08:00
1 parent 0f25dc1511
commit 8db2d1c23b
1 file changed
+48 -2
+48 -2
View File
@@ -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)"""