aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/qapi.py10
-rw-r--r--tests/qapi-schema/flat-union-clash-type.err17
-rw-r--r--tests/qapi-schema/flat-union-clash-type.json8
-rw-r--r--tests/qapi-schema/union-clash-type.err17
-rw-r--r--tests/qapi-schema/union-clash-type.json9
5 files changed, 17 insertions, 44 deletions
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 4b5d574e0d..8d2681b24b 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -544,7 +544,7 @@ def check_union(expr, expr_info):
base = expr.get('base')
discriminator = expr.get('discriminator')
members = expr['data']
- values = {'MAX': '(automatic)'}
+ values = {'MAX': '(automatic)', 'KIND': '(automatic)'}
# Two types of unions, determined by discriminator.
@@ -603,13 +603,19 @@ def check_union(expr, expr_info):
" of branch '%s'" % key)
# If the discriminator names an enum type, then all members
- # of 'data' must also be members of the enum type.
+ # of 'data' must also be members of the enum type, which in turn
+ # must not collide with the discriminator name.
if enum_define:
if key not in enum_define['enum_values']:
raise QAPIExprError(expr_info,
"Discriminator value '%s' is not found in "
"enum '%s'" %
(key, enum_define["enum_name"]))
+ if discriminator in enum_define['enum_values']:
+ raise QAPIExprError(expr_info,
+ "Discriminator name '%s' collides with "
+ "enum value in '%s'" %
+ (discriminator, enum_define["enum_name"]))
# Otherwise, check for conflicts in the generated enum
else:
diff --git a/tests/qapi-schema/flat-union-clash-type.err b/tests/qapi-schema/flat-union-clash-type.err
index 6e64d1d819..b44dd4005c 100644
--- a/tests/qapi-schema/flat-union-clash-type.err
+++ b/tests/qapi-schema/flat-union-clash-type.err
@@ -1,16 +1 @@
-Traceback (most recent call last):
- File "tests/qapi-schema/test-qapi.py", line 55, in <module>
- schema = QAPISchema(sys.argv[1])
- File "scripts/qapi.py", line 1116, in __init__
- self.check()
- File "scripts/qapi.py", line 1299, in check
- ent.check(self)
- File "scripts/qapi.py", line 962, in check
- self.variants.check(schema, members, seen)
- File "scripts/qapi.py", line 1024, in check
- v.check(schema, self.tag_member.type, vseen)
- File "scripts/qapi.py", line 1032, in check
- QAPISchemaObjectTypeMember.check(self, schema, [], seen)
- File "scripts/qapi.py", line 994, in check
- assert self.name not in seen
-AssertionError
+tests/qapi-schema/flat-union-clash-type.json:11: Discriminator name 'type' collides with enum value in 'TestEnum'
diff --git a/tests/qapi-schema/flat-union-clash-type.json b/tests/qapi-schema/flat-union-clash-type.json
index 3db6ea07a8..8f710f08aa 100644
--- a/tests/qapi-schema/flat-union-clash-type.json
+++ b/tests/qapi-schema/flat-union-clash-type.json
@@ -1,9 +1,7 @@
# Flat union branch 'type'
-# FIXME: this triggers an assertion failure. But even with that fixed,
-# we would have a clash in generated C, between the member 'type'
-# inherited from 'Base' and the branch name 'type' within the
-# union. We should either reject this, or munge the generated C to let
-# it compile.
+# Reject this, because we would have a clash in generated C, between the
+# outer tag 'type' and the branch name 'type' within the union.
+# TODO: We could munge the generated C branch name to let it compile.
{ 'enum': 'TestEnum',
'data': [ 'type' ] }
{ 'struct': 'Base',
diff --git a/tests/qapi-schema/union-clash-type.err b/tests/qapi-schema/union-clash-type.err
index 6e64d1d819..a5dead128d 100644
--- a/tests/qapi-schema/union-clash-type.err
+++ b/tests/qapi-schema/union-clash-type.err
@@ -1,16 +1 @@
-Traceback (most recent call last):
- File "tests/qapi-schema/test-qapi.py", line 55, in <module>
- schema = QAPISchema(sys.argv[1])
- File "scripts/qapi.py", line 1116, in __init__
- self.check()
- File "scripts/qapi.py", line 1299, in check
- ent.check(self)
- File "scripts/qapi.py", line 962, in check
- self.variants.check(schema, members, seen)
- File "scripts/qapi.py", line 1024, in check
- v.check(schema, self.tag_member.type, vseen)
- File "scripts/qapi.py", line 1032, in check
- QAPISchemaObjectTypeMember.check(self, schema, [], seen)
- File "scripts/qapi.py", line 994, in check
- assert self.name not in seen
-AssertionError
+tests/qapi-schema/union-clash-type.json:8: Union 'TestUnion' member 'kind' clashes with '(automatic)'
diff --git a/tests/qapi-schema/union-clash-type.json b/tests/qapi-schema/union-clash-type.json
index 52c21f77ea..cfc256b04d 100644
--- a/tests/qapi-schema/union-clash-type.json
+++ b/tests/qapi-schema/union-clash-type.json
@@ -1,10 +1,9 @@
# Union branch 'type'
-# FIXME: this triggers an assertion failure. But even with that fixed,
-# we would have a clash in generated C, between the simple union's
-# implicit tag member 'kind' and the branch name 'kind' within the
-# union. We should either reject this, or munge the generated C to let
-# it compile.
+# Reject this, because we would have a clash in generated C, between the
+# simple union's implicit tag member 'kind' and the branch name 'kind'
+# within the union.
# TODO: Even when the generated C is switched to use 'type' rather than
# 'kind', to match the QMP spelling, the collision should still be detected.
+# Or, we could munge the branch name to allow compilation.
{ 'union': 'TestUnion',
'data': { 'kind': 'int', 'type': 'str' } }