Eric Blake <ebl...@redhat.com> writes: > On 07/29/2015 01:33 AM, Markus Armbruster wrote: >> Eric Blake <ebl...@redhat.com> writes: >> >>> On 07/01/2015 02:21 PM, Markus Armbruster wrote: >>>> The struct generated for a flat union is weird: the members of its >>>> base are at the end, except for the union tag, which is renamed to >>>> 'kind' and put at the beginning. >>> > >>> Therefore, it might be worth mentioning that avoiding the rename to >>> 'kind' is a bug fix, not just a nicer struct :) >> >> Cool! I'll work (a variation of) this test case into my series. > > Another name collision bug: our code generates flat unions as: > > struct BlockdevOptions { > BlockdevDriver driver; > ... > /* End fields inherited from BlockdevOptionsBase. */ > /* union tag is BlockdevDriver driver */ > union { > void *data; > BlockdevOptionsArchipelago *archipelago; > ... > > which means that if we name any of the branches 'data' (that is, if > 'data' is a member of the enum discriminator), things fail to compile. > We could probably fix that by naming our dummy branch '_data'.
Works, because schema names should not begin with '_', except for downstream extensions, which begin with '__RFQDN_'. We don't enforce that, however. I'll include the appended patch. Subject: [PATCH] qapi: Document flaws in checking of names We don't actually enforce our "other than downstream extensions [...], all names should begin with a letter" rule. Add a FIXME. We should reject names that differ only in '_' vs. '.' vs. '-', because they're liable to clash in generated C. Add a FIXME. --- scripts/qapi.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/qapi.py b/scripts/qapi.py index 4af47ef..e61db30 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -341,6 +341,8 @@ def discriminator_find_enum_define(expr): return find_enum(discriminator_type) +# FIXME should enforce "other than downstream extensions [...], all +# names should begin with a letter". valid_name = re.compile('^[a-zA-Z_][a-zA-Z0-9_.-]*$') def check_name(expr_info, source, name, allow_optional = False, enum_member = False): @@ -367,6 +369,8 @@ def check_name(expr_info, source, name, allow_optional = False, def add_name(name, info, meta, implicit = False): global all_names check_name(info, "'%s'" % meta, name) + # FIXME should reject names that differ only in '_' vs. '.' + # vs. '-', because they're liable to clash in generated C. if name in all_names: raise QAPIExprError(info, "%s '%s' is already defined" -- 2.4.3