On 05/03/2016 05:53 AM, Markus Armbruster wrote: > Okay, I'm confused. > > Consider BlockdevRef, defined as > > { 'alternate': 'BlockdevRef', > 'data': { 'definition': 'BlockdevOptions', > 'reference': 'str' } } > > where BlockdevOptions is a (flat) union. Let's clone a BlockdevRef > holding a str. Sequence of calls: > > qapi_BlockdevRef_clone(src) > qapi_clone_visitor_new(src) > // qcv->depth is now 0 > visit_type_BlockdevRef(v, NULL, &dst, &error_abort) > visit_start_alternate(v, NULL, &dst, > sizeof(BlockdevRef), true, &error_abort) > qapi_clone_start_alternate(v, NULL, &dst, > sizeof(BlockdevRef), true, &error_abort)
so far, so good, > qapi_clone_start_struct(v, NULL, &dst, > sizeof(BlockdevRef), &error_abort) Not reached if it holds a string. qapi_clone_start_alternate() sets dst->type to QTYPE_QSTRING, but qapi_clone_start_struct() is only used for QTYPE_QDICT. > // does not increment qcv->depth > visit_type_str(v, NULL, &dst->u.references, &error_abort) > qapi_clone_type_str(v, NULL, &dst->u.references, &error_abort) > assert(qcv->depth) // why does this hold? Either we call: visit_start_alternate() visit_start_struct(NULL) visit_end_struct() visit_end_alternate() or we elide the inner struct visit because the alternate's branch is scalar. Either way, we only need +1 to the depth over the entire alternate, because we only need 1 level of g_memdup() at the time we first enter the alternate. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature