From d0b182392d0281ef780e3effcb82677a004f1f97 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 13 Jul 2016 21:50:13 -0600 Subject: [PATCH] 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 Message-Id: <1468468228-27827-3-git-send-email-eblake@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- scripts/qapi.py | 8 ++++++++ tests/Makefile.include | 1 + tests/qapi-schema/flat-union-incomplete-branch.err | 1 + tests/qapi-schema/flat-union-incomplete-branch.exit | 1 + tests/qapi-schema/flat-union-incomplete-branch.json | 9 +++++++++ tests/qapi-schema/flat-union-incomplete-branch.out | 0 6 files changed, 20 insertions(+) create mode 100644 tests/qapi-schema/flat-union-incomplete-branch.err create mode 100644 tests/qapi-schema/flat-union-incomplete-branch.exit create mode 100644 tests/qapi-schema/flat-union-incomplete-branch.json create mode 100644 tests/qapi-schema/flat-union-incomplete-branch.out diff --git a/scripts/qapi.py b/scripts/qapi.py index b13ae47899..0635bbb0c3 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -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'] diff --git a/tests/Makefile.include b/tests/Makefile.include index 2010b11b6c..a04c1991bb 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -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 diff --git a/tests/qapi-schema/flat-union-incomplete-branch.err b/tests/qapi-schema/flat-union-incomplete-branch.err new file mode 100644 index 0000000000..e826bf0789 --- /dev/null +++ b/tests/qapi-schema/flat-union-incomplete-branch.err @@ -0,0 +1 @@ +tests/qapi-schema/flat-union-incomplete-branch.json:6: Union 'TestUnion' data missing 'value2' branch diff --git a/tests/qapi-schema/flat-union-incomplete-branch.exit b/tests/qapi-schema/flat-union-incomplete-branch.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/flat-union-incomplete-branch.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/flat-union-incomplete-branch.json b/tests/qapi-schema/flat-union-incomplete-branch.json new file mode 100644 index 0000000000..25a411bc83 --- /dev/null +++ b/tests/qapi-schema/flat-union-incomplete-branch.json @@ -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' } } diff --git a/tests/qapi-schema/flat-union-incomplete-branch.out b/tests/qapi-schema/flat-union-incomplete-branch.out new file mode 100644 index 0000000000..e69de29bb2 -- GitLab