fix(typecode): 联合类型中 t.CPtr[...] 下标指针按层级合并,与 TPV 对齐

LLVMTypeMapper 只把裸 t.CPtr 认作指针标记,X | t.CPtr[t.CPtr] 会退化为首段 i8(TPV 定义侧与 TPC 声明侧均为 i8**),跨模块调用点 declare 与定义 ABI 错位:实参传 1 字节、被调用方按 8 字节指针写,ZlibTest 由此触发 ASan heap-buffer-overflow

新增 SymbolUtils.IsCPtrSubscriptNode 判据(对齐 TPV _is_cptr_subscript 的 t.CPtr[...] 判定),_resolve_subscript 与 _resolve_bitor 各增分支,层数复用 TypeAnnotationResolver.from_node(...).PtrCount(先例 HandlesTypeMerge 同手法),使 X | t.CPtr[...] => Ptr^N(X);裸标记分支逐字未改
This commit is contained in:
TermiNexus committed 2026-09-16 07:09:09 +08:00
1 parent 0721568d41
commit 2427a6e992
2 files changed
+44 -1

No files matched your search

+32 -1
View File
@@ -18,7 +18,7 @@ if TYPE_CHECKING:
from lib.core.SymbolTable import SymbolTable
from lib.core.Handles.HandlesBase import CTypeInfo, CTypeHelper, BuiltinTypeMap
from lib.core.SymbolUtils import IsTModule, IsListAnnotation, IsCPtrNode
from lib.core.SymbolUtils import IsTModule, IsListAnnotation, IsCPtrNode, IsCPtrSubscriptNode
from lib.includes import t as _t
from lib.includes.t import CTypeRegistry
@@ -249,6 +249,10 @@ class LLVMTypeMapper:
elem_types.append(self.get_llvm_type_str(slice_node))
if elem_types:
return '{ ' + ', '.join(elem_types) + ' }'
if IsCPtrSubscriptNode(node):
# t.CPtr[T] → Ptr(resolve(T))(对齐 TPV Subscript 分支
# TypeGenResolve.vp:2769-2790;void 首层归一化为 i8*)
return self._add_pointer_level(self.get_llvm_type_str(node.slice))
if IsListAnnotation(node):
slice_node: ast.AST = node.slice
elem_type: str
@@ -267,6 +271,10 @@ class LLVMTypeMapper:
int | t.CPtr → i32* (原逻辑误降级为 i8*)
str | t.CPtr → i8** (原逻辑误降级为 i8*)
(int | t.CPtr) | t.CPtr → i32**(嵌套递归叠加)
T | t.CPtr[...] 一侧为下标指针类型时,另一侧叠加该下标的指针层级 N
(N = 1 + 切片自身层数,不含 struct 吸收,对齐 TPV BinOp 下标分支
TypeGenResolve.vp:2596-2639):
t.CUInt8T | t.CPtr[t.CPtr] → i8**(原逻辑误降级为首段 i8)
"""
left: str = self.get_llvm_type_str(node.left)
right: str = self.get_llvm_type_str(node.right)
@@ -276,6 +284,11 @@ class LLVMTypeMapper:
return self._add_pointer_level(left)
if left_is_cptr:
return self._add_pointer_level(right)
# t.CPtr[...] 下标指针标记:X | t.CPtr[...] → Ptr^N(X)
if IsCPtrSubscriptNode(node.right):
return self._add_pointer_levels(left, self._cptr_subscript_ptr_level(node.right))
if IsCPtrSubscriptNode(node.left):
return self._add_pointer_levels(right, self._cptr_subscript_ptr_level(node.left))
if right and right.endswith('*'):
return right
if left and left.endswith('*'):
@@ -296,6 +309,24 @@ class LLVMTypeMapper:
return ty + '*'
return ty + '*'
def _add_pointer_levels(self, ty: str, count: int) -> str:
"""给类型字符串叠加 count 层指针(void/void* 首层归一化为 i8*)。"""
result: str = ty
for _ in range(count):
result = self._add_pointer_level(result)
return result
def _cptr_subscript_ptr_level(self, node: ast.AST) -> int:
"""t.CPtr[T] 下标指针标记贡献的指针层级 N(= 1 + 切片自身层数)。
复用定义侧解析器 TypeAnnotationResolver.from_node(其 _from_node_subscript
已实现 t.CPtr[T] → Ptr(T) 的层级叠加,见 TypeAnnotationResolver.py:756-783),
与 HandlesTypeMerge._HandleSubscript(HandlesTypeMerge.py:512-531)同口径。
调用前须经 IsCPtrSubscriptNode 判据过滤,故 PtrCount 至少为 1。
"""
from lib.core.TypeAnnotationResolver import TypeAnnotationResolver as _TAR
return _TAR.from_node(node, self._symtab).PtrCount
def _resolve_call(self, node: ast.Call) -> str:
"""解析 ast.Call 节点"""
if isinstance(node.func, ast.Attribute):
+12
View File
@@ -238,3 +238,15 @@ def IsCPtrNode(node: ast.AST) -> bool:
and isinstance(node.value, ast.Name)
and node.value.id == 't'
and node.attr == 'CPtr')
def IsCPtrSubscriptNode(node: ast.AST) -> bool:
"""检查节点是否为 t.CPtr[T] 下标指针类型(非裸标记,裸标记见 IsCPtrNode)。
与 TPV TypeGenResolve._is_cptr_subscript(TypeGenResolve.vp:1485-1505)同口径:
value 必须是 t.CPtr 属性引用(只认 t 前缀,c.CPtr[...] 不认);
切片内的指针层级不限(t.CPtr[t.CPtr]、t.CPtr[t.CPtr[t.CInt]] 均命中)。
链式写法 t.CPtr[T][T](value 是 Subscript)两套编译器均不认作该标记。
"""
return (isinstance(node, ast.Subscript)
and IsCPtrNode(node.value))