From 813b59e25f010945f3f4a94d993d1cc474cd2843 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 14 Oct 2026 17:57:01 +0800 Subject: [PATCH] =?UTF-8?q?fix(viperc):=20=E4=BF=AE=E6=AD=A3=20(expr).meth?= =?UTF-8?q?od()=20=E6=8E=A5=E6=94=B6=E8=80=85=E8=AF=AF=E5=85=A5=20get=5Fat?= =?UTF-8?q?tribute=5Fptr=20=E5=AF=BC=E8=87=B4=E7=9A=84=20strcmp(=5F,0x1)?= =?UTF-8?q?=20=E5=B4=A9=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 表达式接收者分支(L1236 设计上可收 BinOp/Subscript/Call)在接收者求值非指针时会调 get_attribute_ptr;该 API 只接受 Attribute,内部直接强转成 ast.Attribute 并读 .attr,对别的节点会命中偏移 9 的字段:BinOp 的 op(OpKind.Sub=1)、Name 的 ctx(ASTCtx.Store=1)等,于是把整数 1 当字符串传给 strcmp → ASan access-violation on 0x1 - 现在仅当接收者确为 ast.Attribute 时才走“取字段地址”,其余节点保持已翻译的接收者值(与旧实现的回退结果一致) - 现场:Test/OopInheritTest/App/main.vp 的 (a3 * 2.0 - a4).cross(a5),接收者 BinOp 的 op=Sub=1 --- App/lib/core/Gen/Call/CallGenDispatch.vp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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