From 09df9c9efbeb7aa361bfebb8e59e1b71754e4b63 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 20 May 2022 00:41:52 -0700 Subject: ffi: bugfix: clone of type points to old self. * ffi.c (ffi_type_copy, ffi_type_copy_new_ops): The cloned txr_ffi_type structure must have a self member which points to the new cobj, not the original one. Otherwise things are inconsistent. For instance if the clone is being made for the purposes of adjusting alignment, any operation which chases the self pointer will be accessing incorrect attributes. One example of this is (alignof foo.bar) where if bar is the clone of a type, this will incorrectly report the alignment of the original from which bar was cloned, and the original alignment, not the adjusted alignment is reported. --- ffi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ffi.c b/ffi.c index 4fbb6d28..437713d7 100644 --- a/ffi.c +++ b/ffi.c @@ -3217,14 +3217,18 @@ static val ffi_type_copy(val orig) { struct txr_ffi_type *otft = ffi_type_struct(orig); struct txr_ffi_type *ctft = otft->clone(otft); - return cobj(coerce(mem_t *, ctft), orig->co.cls, orig->co.ops); + val obj = cobj(coerce(mem_t *, ctft), orig->co.cls, orig->co.ops); + ctft->self = obj; + return obj; } static val ffi_type_copy_new_ops(val orig, struct cobj_ops *ops) { struct txr_ffi_type *otft = ffi_type_struct(orig); struct txr_ffi_type *ctft = otft->clone(otft); - return cobj(coerce(mem_t *, ctft), orig->co.cls, ops); + val obj = cobj(coerce(mem_t *, ctft), orig->co.cls, ops); + ctft->self = obj; + return obj; } static struct txr_ffi_type *ffi_simple_clone(struct txr_ffi_type *orig) -- cgit v1.2.3