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 - 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 - 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' } }