From 2427a6e99298c01242c0ff2c789c74c4c75b7cfa Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 16 Sep 2026 07:09:09 +0800 Subject: [PATCH] =?UTF-8?q?fix(typecode):=20=E8=81=94=E5=90=88=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E4=B8=AD=20t.CPtr[...]=20=E4=B8=8B=E6=A0=87=E6=8C=87?= =?UTF-8?q?=E9=92=88=E6=8C=89=E5=B1=82=E7=BA=A7=E5=90=88=E5=B9=B6=EF=BC=8C?= =?UTF-8?q?=E4=B8=8E=20TPV=20=E5=AF=B9=E9=BD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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);裸标记分支逐字未改 --- lib/core/LLVMTypeMapper.py | 33 ++++++++++++++++++++++++++++++++- lib/core/SymbolUtils.py | 12 ++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/core/LLVMTypeMapper.py b/lib/core/LLVMTypeMapper.py index 119aa26..90b4939 100644 --- a/lib/core/LLVMTypeMapper.py +++ b/lib/core/LLVMTypeMapper.py @@ -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): diff --git a/lib/core/SymbolUtils.py b/lib/core/SymbolUtils.py index dc02047..827a4e6 100644 --- a/lib/core/SymbolUtils.py +++ b/lib/core/SymbolUtils.py @@ -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))