Quoting Paolo Bonzini (2014-09-12 11:29:46) > Il 12/09/2014 18:17, Michael Roth ha scritto: > > Quoting Paolo Bonzini (2014-09-12 10:39:49) > >> Il 12/09/2014 17:34, Michael Roth ha scritto: > >>> > >>> { 'union': 'UserDefUnion', > >>> 'base': 'UserDefZero', > >>> 'data': { 'a' : 'int', 'b' : 'UserDefB' } } > >>> > >>> If UserDefUnion.a is 0, UserDefUnion.data will cast it to a NULL value and > >>> cause the output visitor to bail, when really it should just be left to > >>> continue on serializing the integer. > >> > >> In the case of dealloc, that'd be okay because the dealloc visit would > >> do nothing for KIND_A, right? > > > > Yup that should be fine for the dealloc visitor. With this series we never > > actually visit the int in this case though due to this quirk. But that's > > okay because it's not an allocated type and the dealloc visitor doesn't need > > to do anything anyway. (It's a bit wonky, but since that reliance on > > implementation details now lives in the visitor implementation of > > visit_start_union it's reasonably contained at least) > > > > But if we're looking at extending visit_start_union for use in something > > like > > an output visitor, this would need to be addressed some other way, since > > skipping scalar fields because they're 0 is a bug there. > > I guess it would be something like > > has_data = (kind < KIND_MAX) && (is_scalar[kind] || !!data) > > That could be done in qapi-visit.py if we were so inclined...
Yah that should be everything we'd need, but we'd need to make other changes similar to what Fam originally proposed to ensure kind < KIND_MAX implies that kind has actually been initialized. Or, we'd need to make all enums start at 1, and reserve 0 for INVALID. Not aware if any option except those 2 atm. However, we could still actually implement what you proposed for has_data as is, and make use of the fact that even if kind happens to be invalid/uninitialized, we still won't attempt to visit/dereference the value in an output visitor (if they implement visit_start_union) if that value is NULL or scalar(0). So, it makes at least one case safer. It wouldn't stop us for doing something like serializing a char* as an integer or something along that line though, so it's somewhat of a false assurance unless we do something to validate .kind. > > Paolo