取消了 i8* == i8* 实际使用 strcmp 的规则
This commit is contained in:
@@ -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: 值比较(调用 strcmp),None 比较用地址
|
||||
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)):
|
||||
|
||||
Reference in New Issue
Block a user