fix(viperc): 修正 (expr).method() 接收者误入 get_attribute_ptr 导致的 strcmp(_,0x1) 崩溃
- 表达式接收者分支(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
This commit is contained in:
1 parent
ee3337f3c4
commit
813b59e25f
1 file changed
+6
-1
@@ -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
|
||||
|
||||
Reference in new issue
Block a user