qapi: Require all branches of flat union enum to be covered

We were previously enforcing that all flat union branches were
found in the corresponding enum, but not that all enum values
were covered by branches.  The resulting generated code would
abort() if the user passes the uncovered enum value.

We don't automatically treat non-present branches in a flat
union as empty types, for symmetry with simple unions (there,
the enum type is generated from the list of all branches, so
there is no way to omit a branch but still have it be part of
the union).

A later patch will add shorthand so that branches that are empty
in flat unions can be declared as 'branch':{} instead of
'branch':'Empty', to avoid the need for an otherwise useless
explicit empty type.  [Such shorthand for simple unions is a bit
harder to justify, since we would still have to generate a
wrapper type that parses 'data':{}, rather than truly being an
empty branch with no additional siblings to the 'type' member.]

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1468468228-27827-3-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
master
Eric Blake 2016-07-13 21:50:13 -06:00 committed by Markus Armbruster
parent cebea51057
commit d0b182392d
6 changed files with 20 additions and 0 deletions

View File

@ -612,6 +612,14 @@ def check_union(expr, expr_info):
"enum '%s'" %
(key, enum_define["enum_name"]))
# If discriminator is user-defined, ensure all values are covered
if enum_define:
for value in enum_define['enum_values']:
if value not in members.keys():
raise QAPIExprError(expr_info,
"Union '%s' data missing '%s' branch"
% (name, value))
def check_alternate(expr, expr_info):
name = expr['alternate']

View File

@ -326,6 +326,7 @@ qapi-schema += flat-union-base-any.json
qapi-schema += flat-union-base-union.json
qapi-schema += flat-union-clash-member.json
qapi-schema += flat-union-empty.json
qapi-schema += flat-union-incomplete-branch.json
qapi-schema += flat-union-inline.json
qapi-schema += flat-union-int-branch.json
qapi-schema += flat-union-invalid-branch-key.json

View File

@ -0,0 +1 @@
tests/qapi-schema/flat-union-incomplete-branch.json:6: Union 'TestUnion' data missing 'value2' branch

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,9 @@
# we require all branches of the union to be covered
{ 'enum': 'TestEnum',
'data': [ 'value1', 'value2' ] }
{ 'struct': 'TestTypeA',
'data': { 'string': 'str' } }
{ 'union': 'TestUnion',
'base': { 'type': 'TestEnum' },
'discriminator': 'type',
'data': { 'value1': 'TestTypeA' } }