From 7d6917762c870b0d1a9c65a507dc4c67fa9cc28c Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 7 Aug 2026 22:36:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(core):=20=E6=95=B0=E7=BB=84=E4=B8=8B?= =?UTF-8?q?=E6=A0=87=20<32=20=E4=BD=8D=E7=B4=A2=E5=BC=95=20zext=20?= =?UTF-8?q?=E5=88=B0=20i32=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=AD=97=E8=8A=82?= =?UTF-8?q?=E7=B4=A2=E5=BC=95=E8=B6=8A=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/lib/core/Handles/HandlesExpr.vp | 32 +++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/App/lib/core/Handles/HandlesExpr.vp b/App/lib/core/Handles/HandlesExpr.vp index fc9cc68..b62e870 100644 --- a/App/lib/core/Handles/HandlesExpr.vp +++ b/App/lib/core/Handles/HandlesExpr.vp @@ -191,6 +191,26 @@ def is_array_type(ty: llvmlite.LLVMType | t.CPtr) -> int: return 0 +# ============================================================ +# _zext_index_to_i32 - 数组下标索引零扩展 +# +# LLVM GEP 对窄整数索引默认符号扩展:i8 0xE2(226) 会被当成 -30, +# 导致数组下标越界读(字节 >= 128 的乱码根因)。 +# 数组下标语义为非负,<32 位整数索引一律 zext 到 i32。 +# 仅用于数组 GEP;指针负偏移(p[-1])不经过此路径,不受影响。 +# ============================================================ +def _zext_index_to_i32(builder: llvmlite.IRBuilder | t.CPtr, + idx_val: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr: + """将 <32 位整数下标零扩展到 i32(数组下标非负语义)""" + if idx_val is None or idx_val.Ty is None or builder is None: + return idx_val + idx_bits: int = get_llvm_type_bits(idx_val.Ty) + if idx_bits != 0 and idx_bits < 32: + i32_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(builder.Pool) + return llvmlite.build_zext(builder, idx_val, i32_ty) + return idx_val + + # ============================================================ # _get_custom_struct_cls_nm - 检查类型是否为已注册的自定义结构体 # @@ -2268,7 +2288,8 @@ def translate_subscript(builder: llvmlite.IRBuilder | t.CPtr, case llvmlite.LLVMType.Array(elem_ty, count): # 数组遍历: getelementptr [N x elem_ty], ... , i32 0, i32 %idx elem_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_array( - builder, pointee, elem_ty, alloca, idx_val) + builder, pointee, elem_ty, alloca, + _zext_index_to_i32(builder, idx_val)) if elem_ptr is not None: return llvmlite.build_load(builder, elem_ty, elem_ptr) return None @@ -2388,7 +2409,8 @@ def translate_subscript(builder: llvmlite.IRBuilder | t.CPtr, match elem_ty2: case llvmlite.LLVMType.Array(arr_elem_ty2, arr_count2): elem_ptr3: llvmlite.Value | t.CPtr = llvmlite.build_gep_array( - builder, elem_ty2, arr_elem_ty2, ptr_val, idx_val) + builder, elem_ty2, arr_elem_ty2, ptr_val, + _zext_index_to_i32(builder, idx_val)) if elem_ptr3 is not None: return llvmlite.build_load(builder, arr_elem_ty2, elem_ptr3) return None @@ -3065,7 +3087,8 @@ def get_subscript_ptr(builder: llvmlite.IRBuilder | t.CPtr, case llvmlite.LLVMType.Array(elem_ty, count): # 数组遍历 return llvmlite.build_gep_array( - builder, pointee, elem_ty, alloca, idx_val) + builder, pointee, elem_ty, alloca, + _zext_index_to_i32(builder, idx_val)) case llvmlite.LLVMType.Ptr(inner_ty): # inner_ty 是 Ptr 说明 alloca.Ty 是三重指针, # 即 X|t.CPtr 当 X 本身是指针类型 (如 T=AST|t.CPtr, T|t.CPtr=AST**)。 @@ -3120,7 +3143,8 @@ def get_subscript_ptr(builder: llvmlite.IRBuilder | t.CPtr, match elem_ty2: case llvmlite.LLVMType.Array(arr_elem_ty, arr_count): return llvmlite.build_gep_array( - builder, elem_ty2, arr_elem_ty, ptr_val, idx_val) + builder, elem_ty2, arr_elem_ty, ptr_val, + _zext_index_to_i32(builder, idx_val)) case _: pass # 自定义结构体 (如 self._ht[key]): 返回 None,