fix(core): 数组下标 <32 位索引 zext 到 i32,修复字节索引越界
This commit is contained in:
1 parent
d6690c6e39
commit
7d6917762c
1 file changed
+28
-4
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user