diff --git a/App/lib/core/Gen/Call/CallGenDispatch.vp b/App/lib/core/Gen/Call/CallGenDispatch.vp index 069159d..29ebe6e 100644 --- a/App/lib/core/Gen/Call/CallGenDispatch.vp +++ b/App/lib/core/Gen/Call/CallGenDispatch.vp @@ -1266,13 +1266,18 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): if expr_cls_nm is not None: # Value-type receivers (embedded struct fields) must pass the field address (GEP), # not the loaded struct value, or the ABI mismatches and the callee dereferences it as this. + # **只有 Attribute 接收者才是"字段"**:本分支的接收者按 L1236 的设计可以是 + # BinOp/Subscript/Call(如 `(p - q).method()`),它们绝不能进 get_attribute_ptr + # —— 该 API 只接受 Attribute,内部直接强转成 ast.Attribute 并读 `.attr`; + # 对别的节点就会命中偏移 9 的那个字段(BinOp 的 op=1 / Name 的 ctx=1 …), + # 把整数 1 当字符串传给 strcmp → ASan 在 0x1 上 access-violation。 expr_is_ptr: int = 0 match expr_obj.Ty: case mlirlite.LLVMType.Ptr(expr_ptr_inner): expr_is_ptr = 1 case _: expr_is_ptr = 0 - if expr_is_ptr == 0: + if expr_is_ptr == 0 and expr_method_at.value.kind() == ast.ASTKind.Attribute: expr_addr: mlirlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr(builder, pool, mod, expr_method_at.value, trans) if expr_addr is not None: expr_obj = expr_addr if hit_box is not None: hit_box[0] = 1