fix(tpc): 局部 str*/str|t.CPtr 注解不再被压平成 i8*(补 PtrCount<=1 豁免)
类别 b(机制漏豁免):`TypeInfo.IsStr` 对**任何** CChar + 指针层都为真, 局部 AnnAssign 处却无条件把 PtrCount 压成 1,导致 `argv_arr: str*` 被声明为 i8*,而同名模块级全局 `_argv: str*` 走 HandlesAssign._EmitGlobalAnnAssignLlvm 的 FromNode 得到 i8**,于是 `_argv = argv_arr` 被 「指针隐式转换已禁止(层数不同):i8* → i8**」拦下(includes/sys.vp:114、 _init_argv_posix 同款 L148)。 同一规则在 HandlesFunctions.py:599 / 690 / 722 / 1434 / 1514 / 1602 / 1662 与 HandlesImports.py:1440 / 1542 都已带 `IsStr and PtrCount <= 1` 豁免(注释写明 "str | t.CPtr 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 数组),不能压平"), 唯独 HandlesAnnAssign.py:452 漏了这一条 —— 本次补齐:只压平 PtrCount<=1, `str*` / `str | t.CPtr` 保持 i8**;_str 影子结构与 var_ptr_element(8 字节步长) 标记仍照旧执行。 判据(不猜): 1. TPV 参考实现产物 Test/SysLibTest/.tpv_build/temp/0c/0cc16828640f94b7.ll: `@"0cc16828640f94b7._argv" = global i8**`、_init_argv_win32 内 `alloca i8**`(argv_arr)、`store i8** %x, i8*** @"..._argv"` —— 局部与全局 同为 i8**。 2. TPC 全局侧 FromNode 对 `str*` 给出 PtrCount=2(CChar + str 的 1 层 + CPtr 的 1 层)。 重编即可验证 sys.vp 第 84/114 行一致。
This commit is contained in:
1 parent
25cda80995
commit
8c831a38d3
1 file changed
+12
-4
@@ -450,10 +450,18 @@ class AnnAssignHandle(BaseHandle):
|
||||
Gen._record_var_signedness(VarName, TypeInfo.IsUInt)
|
||||
return
|
||||
if TypeInfo.IsStr or (isinstance(Node.annotation, ast.Name) and Node.annotation.id == 'str'):
|
||||
TypeInfo = CTypeInfo()
|
||||
TypeInfo.BaseType = t.CChar()
|
||||
TypeInfo.PtrCount = 1
|
||||
IsPtr = True
|
||||
# 仅指针层数 <= 1 才算裸 str/bytes(i8*),可以压平:`str | t.CPtr` /
|
||||
# `str*` 合并后 IsStr=True 但 PtrCount=2(i8**,如 argv 指针数组),
|
||||
# 压平会让局部变量比模块级同名全局槽少一层指针
|
||||
# (全局走 HandlesAssign._EmitGlobalAnnAssignLlvm 的 FromNode,得到 i8**),
|
||||
# 于是 includes/sys.vp `_argv = argv_arr` 被指针隐式转换 fail-fast 拦下。
|
||||
# 与 HandlesFunctions.py:599 / HandlesImports.py:1440 的
|
||||
# `IsStr and PtrCount <= 1` 同一条规则源。
|
||||
if TypeInfo.PtrCount <= 1:
|
||||
TypeInfo = CTypeInfo()
|
||||
TypeInfo.BaseType = t.CChar()
|
||||
TypeInfo.PtrCount = 1
|
||||
IsPtr = True
|
||||
# FakeDuck: 为 str 变量创建影子结构体 a__meta__ (栈上, per-instance)
|
||||
# a 保持为 char* 用于 printf; a__meta__ 存储 __data__ 和 __mbuddy__ 字段
|
||||
# 仅对 str 类型创建,bytes 和 t.CChar|t.CPtr 不创建
|
||||
|
||||
Reference in new issue
Block a user