取消了 i8* == i8* 实际使用 strcmp 的规则

This commit is contained in:
2026-07-30 21:56:41 +08:00
parent cfc30d735c
commit 377b60fd67
54 changed files with 129 additions and 3730 deletions

View File

@@ -385,7 +385,7 @@ class ExprOpsHandle(BaseHandle):
if isinstance(RightVal, ir.Constant) and RightVal.constant == 0:
RightVal = ir.Constant(LeftVal.type, None)
else:
# 不将整数转为指针(避免 strcmp 解引用无效地址),改为将指针转为整数走正常 ==
# 指针 vs 非零整数: 将指针转为整数走正常 ==(地址值比较)
LeftVal = Gen.builder.ptrtoint(LeftVal, RightVal.type, name="ptr2int_cmp")
elif isinstance(RightVal.type, ir.PointerType) and isinstance(LeftVal.type, ir.IntType):
if isinstance(RightVal.type.pointee, ir.IntType) and RightVal.type.pointee.width == 8 and isinstance(LeftVal.type, ir.IntType) and LeftVal.type.width == 8:
@@ -394,7 +394,7 @@ class ExprOpsHandle(BaseHandle):
if isinstance(LeftVal, ir.Constant) and LeftVal.constant == 0:
LeftVal = ir.Constant(RightVal.type, None)
else:
# 不将整数转为指针(避免 strcmp 解引用无效地址),改为将指针转为整数走正常 ==
# 非零整数 vs 指针: 将指针转为整数走正常 ==(地址值比较)
RightVal = Gen.builder.ptrtoint(RightVal, LeftVal.type, name="ptr2int_cmp")
# is / is not: 地址比较指针或值比较int
if ComparatorSymbol in ('is', 'is not'):
@@ -408,20 +408,8 @@ class ExprOpsHandle(BaseHandle):
if ComparatorSymbol == 'is not':
val_cmp = Gen.builder.not_(val_cmp, name="is_not_result")
return val_cmp
# str/bytes == str/bytes: 值比较(调用 strcmpNone 比较用地址
if ComparatorSymbol in ('==', '!='):
if (isinstance(LeftVal.type, ir.PointerType) and isinstance(LeftVal.type.pointee, ir.IntType) and LeftVal.type.pointee.width == 8
and isinstance(RightVal.type, ir.PointerType) and isinstance(RightVal.type.pointee, ir.IntType) and RightVal.type.pointee.width == 8):
left_is_null: bool = isinstance(LeftVal, ir.Constant) and LeftVal.constant is None
right_is_null: bool = isinstance(RightVal, ir.Constant) and RightVal.constant is None
if not (left_is_null or right_is_null):
strcmp_func = Gen.get_or_declare_c_func('strcmp', ir.FunctionType(ir.IntType(32), [ir.IntType(8).as_pointer(), ir.IntType(8).as_pointer()]))
cmp_result = Gen.builder.call(strcmp_func, [LeftVal, RightVal], name="str_eq_cmp")
zero = ir.Constant(ir.IntType(32), 0)
eq_result = Gen.builder.icmp_signed('==', cmp_result, zero, name="str_eq")
if ComparatorSymbol == '!=':
eq_result = Gen.builder.not_(eq_result, name="str_neq")
return eq_result
# == / !=: 指针间做地址比较C-Like 语义,不隐式调用 strcmp
# 如需字符串内容比较,应显式调用 string.strcmp()
if isinstance(LeftVal.type, ir.PointerType) and isinstance(RightVal.type, ir.PointerType):
result = Gen.builder.icmp_unsigned(ComparatorSymbol, LeftVal, RightVal, name="cmpresult")
elif isinstance(LeftVal.type, (ir.FloatType, ir.DoubleType)) or isinstance(RightVal.type, (ir.FloatType, ir.DoubleType)):