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
|
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 - 检查类型是否为已注册的自定义结构体
|
# _get_custom_struct_cls_nm - 检查类型是否为已注册的自定义结构体
|
||||||
#
|
#
|
||||||
@@ -2268,7 +2288,8 @@ def translate_subscript(builder: llvmlite.IRBuilder | t.CPtr,
|
|||||||
case llvmlite.LLVMType.Array(elem_ty, count):
|
case llvmlite.LLVMType.Array(elem_ty, count):
|
||||||
# 数组遍历: getelementptr [N x elem_ty], ... , i32 0, i32 %idx
|
# 数组遍历: getelementptr [N x elem_ty], ... , i32 0, i32 %idx
|
||||||
elem_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
|
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:
|
if elem_ptr is not None:
|
||||||
return llvmlite.build_load(builder, elem_ty, elem_ptr)
|
return llvmlite.build_load(builder, elem_ty, elem_ptr)
|
||||||
return None
|
return None
|
||||||
@@ -2388,7 +2409,8 @@ def translate_subscript(builder: llvmlite.IRBuilder | t.CPtr,
|
|||||||
match elem_ty2:
|
match elem_ty2:
|
||||||
case llvmlite.LLVMType.Array(arr_elem_ty2, arr_count2):
|
case llvmlite.LLVMType.Array(arr_elem_ty2, arr_count2):
|
||||||
elem_ptr3: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
|
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:
|
if elem_ptr3 is not None:
|
||||||
return llvmlite.build_load(builder, arr_elem_ty2, elem_ptr3)
|
return llvmlite.build_load(builder, arr_elem_ty2, elem_ptr3)
|
||||||
return None
|
return None
|
||||||
@@ -3065,7 +3087,8 @@ def get_subscript_ptr(builder: llvmlite.IRBuilder | t.CPtr,
|
|||||||
case llvmlite.LLVMType.Array(elem_ty, count):
|
case llvmlite.LLVMType.Array(elem_ty, count):
|
||||||
# 数组遍历
|
# 数组遍历
|
||||||
return llvmlite.build_gep_array(
|
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):
|
case llvmlite.LLVMType.Ptr(inner_ty):
|
||||||
# inner_ty 是 Ptr 说明 alloca.Ty 是三重指针,
|
# inner_ty 是 Ptr 说明 alloca.Ty 是三重指针,
|
||||||
# 即 X|t.CPtr 当 X 本身是指针类型 (如 T=AST|t.CPtr, T|t.CPtr=AST**)。
|
# 即 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:
|
match elem_ty2:
|
||||||
case llvmlite.LLVMType.Array(arr_elem_ty, arr_count):
|
case llvmlite.LLVMType.Array(arr_elem_ty, arr_count):
|
||||||
return llvmlite.build_gep_array(
|
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 _:
|
case _:
|
||||||
pass
|
pass
|
||||||
# 自定义结构体 (如 self._ht[key]): 返回 None,
|
# 自定义结构体 (如 self._ht[key]): 返回 None,
|
||||||
|
|||||||
Reference in new issue
Block a user