summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/qapi-types.py13
-rw-r--r--scripts/qapi.py89
-rw-r--r--tests/qapi-schema/alternate-array.err1
-rw-r--r--tests/qapi-schema/alternate-array.exit2
-rw-r--r--tests/qapi-schema/alternate-array.json2
-rw-r--r--tests/qapi-schema/alternate-array.out4
-rw-r--r--tests/qapi-schema/alternate-base.err1
-rw-r--r--tests/qapi-schema/alternate-base.exit2
-rw-r--r--tests/qapi-schema/alternate-base.json2
-rw-r--r--tests/qapi-schema/alternate-base.out4
-rw-r--r--tests/qapi-schema/alternate-clash.err1
-rw-r--r--tests/qapi-schema/alternate-clash.exit2
-rw-r--r--tests/qapi-schema/alternate-clash.json2
-rw-r--r--tests/qapi-schema/alternate-clash.out3
-rw-r--r--tests/qapi-schema/alternate-conflict-dict.err1
-rw-r--r--tests/qapi-schema/alternate-conflict-dict.exit2
-rw-r--r--tests/qapi-schema/alternate-conflict-dict.json2
-rw-r--r--tests/qapi-schema/alternate-conflict-dict.out6
-rw-r--r--tests/qapi-schema/alternate-conflict-string.err1
-rw-r--r--tests/qapi-schema/alternate-conflict-string.exit2
-rw-r--r--tests/qapi-schema/alternate-conflict-string.json2
-rw-r--r--tests/qapi-schema/alternate-conflict-string.out5
-rw-r--r--tests/qapi-schema/alternate-nested.err1
-rw-r--r--tests/qapi-schema/alternate-nested.exit2
-rw-r--r--tests/qapi-schema/alternate-nested.json2
-rw-r--r--tests/qapi-schema/alternate-nested.out5
-rw-r--r--tests/qapi-schema/alternate-unknown.err1
-rw-r--r--tests/qapi-schema/alternate-unknown.exit2
-rw-r--r--tests/qapi-schema/alternate-unknown.json2
-rw-r--r--tests/qapi-schema/alternate-unknown.out3
-rw-r--r--tests/qapi-schema/flat-union-bad-base.err2
-rw-r--r--tests/qapi-schema/flat-union-bad-base.json2
-rw-r--r--tests/qapi-schema/flat-union-bad-discriminator.err1
-rw-r--r--tests/qapi-schema/flat-union-bad-discriminator.exit2
-rw-r--r--tests/qapi-schema/flat-union-bad-discriminator.json2
-rw-r--r--tests/qapi-schema/flat-union-bad-discriminator.out10
-rw-r--r--tests/qapi-schema/flat-union-inline.err2
-rw-r--r--tests/qapi-schema/flat-union-inline.json2
-rw-r--r--tests/qapi-schema/flat-union-no-base.err2
-rw-r--r--tests/qapi-schema/flat-union-no-base.json2
-rw-r--r--tests/qapi-schema/union-bad-branch.err1
-rw-r--r--tests/qapi-schema/union-bad-branch.exit2
-rw-r--r--tests/qapi-schema/union-bad-branch.json2
-rw-r--r--tests/qapi-schema/union-bad-branch.out6
-rw-r--r--tests/qapi-schema/union-max.err1
-rw-r--r--tests/qapi-schema/union-max.exit2
-rw-r--r--tests/qapi-schema/union-max.json2
-rw-r--r--tests/qapi-schema/union-max.out3
48 files changed, 110 insertions, 103 deletions
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index f6fb930279..2390887f28 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -181,17 +181,8 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
name=name)
for key in members:
- qapi_type = members[key]
- if builtin_types.has_key(qapi_type):
- qtype = builtin_types[qapi_type]
- elif find_struct(qapi_type):
- qtype = "QTYPE_QDICT"
- elif find_union(qapi_type):
- qtype = "QTYPE_QDICT"
- elif find_enum(qapi_type):
- qtype = "QTYPE_QSTRING"
- else:
- assert False, "Invalid anonymous union member"
+ qtype = find_anonymous_member_qtype(members[key])
+ assert qtype, "Invalid anonymous union member"
ret += mcgen('''
[ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 438468e3aa..5f0f699994 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -224,6 +224,23 @@ def find_base_fields(base):
return None
return base_struct_define['data']
+# Return the qtype of an anonymous union branch, or None on error.
+def find_anonymous_member_qtype(qapi_type):
+ if builtin_types.has_key(qapi_type):
+ return builtin_types[qapi_type]
+ elif find_struct(qapi_type):
+ return "QTYPE_QDICT"
+ elif find_enum(qapi_type):
+ return "QTYPE_QSTRING"
+ else:
+ union = find_union(qapi_type)
+ if union:
+ discriminator = union.get('discriminator')
+ if discriminator == {}:
+ return None
+ return "QTYPE_QDICT"
+ return None
+
# Return the discriminator enum define if discriminator is specified as an
# enum type, otherwise return None.
def discriminator_find_enum_define(expr):
@@ -258,6 +275,8 @@ def check_union(expr, expr_info):
base = expr.get('base')
discriminator = expr.get('discriminator')
members = expr['data']
+ values = { 'MAX': '(automatic)' }
+ types_seen = {}
# If the object has a member 'base', its value must name a complex type,
# and there must be a discriminator.
@@ -266,26 +285,35 @@ def check_union(expr, expr_info):
raise QAPIExprError(expr_info,
"Union '%s' requires a discriminator to go "
"along with base" %name)
- base_fields = find_base_fields(base)
- if not base_fields:
- raise QAPIExprError(expr_info,
- "Base '%s' is not a valid type"
- % base)
# If the union object has no member 'discriminator', it's a
# simple union. If 'discriminator' is {}, it is an anonymous union.
- if not discriminator or discriminator == {}:
+ if discriminator is None or discriminator == {}:
enum_define = None
+ if base is not None:
+ raise QAPIExprError(expr_info,
+ "Union '%s' must not have a base"
+ % name)
# Else, it's a flat union.
else:
- # The object must have a member 'base'.
- if not base:
+ # The object must have a string member 'base'.
+ if not isinstance(base, str):
raise QAPIExprError(expr_info,
- "Flat union '%s' must have a base field"
+ "Flat union '%s' must have a string base field"
% name)
+ base_fields = find_base_fields(base)
+ if not base_fields:
+ raise QAPIExprError(expr_info,
+ "Base '%s' is not a valid type"
+ % base)
+
# The value of member 'discriminator' must name a member of the
# base type.
+ if not isinstance(discriminator, str):
+ raise QAPIExprError(expr_info,
+ "Flat union '%s' discriminator must be a string"
+ % name)
discriminator_type = base_fields.get(discriminator)
if not discriminator_type:
raise QAPIExprError(expr_info,
@@ -301,15 +329,42 @@ def check_union(expr, expr_info):
# Check every branch
for (key, value) in members.items():
- # If this named member's value names an enum type, then all members
+ # If the discriminator names an enum type, then all members
# of 'data' must also be members of the enum type.
- if enum_define and not key in enum_define['enum_values']:
- raise QAPIExprError(expr_info,
- "Discriminator value '%s' is not found in "
- "enum '%s'" %
- (key, enum_define["enum_name"]))
- # Todo: add checking for values. Key is checked as above, value can be
- # also checked here, but we need more functions to handle array case.
+ if enum_define:
+ if not key in enum_define['enum_values']:
+ raise QAPIExprError(expr_info,
+ "Discriminator value '%s' is not found in "
+ "enum '%s'" %
+ (key, enum_define["enum_name"]))
+
+ # Otherwise, check for conflicts in the generated enum
+ else:
+ c_key = _generate_enum_string(key)
+ if c_key in values:
+ raise QAPIExprError(expr_info,
+ "Union '%s' member '%s' clashes with '%s'"
+ % (name, key, values[c_key]))
+ values[c_key] = key
+
+ # Ensure anonymous unions have no type conflicts.
+ if discriminator == {}:
+ if isinstance(value, list):
+ raise QAPIExprError(expr_info,
+ "Anonymous union '%s' member '%s' must "
+ "not be array type" % (name, key))
+ qtype = find_anonymous_member_qtype(value)
+ if not qtype:
+ raise QAPIExprError(expr_info,
+ "Anonymous union '%s' member '%s' has "
+ "invalid type '%s'" % (name, key, value))
+ if qtype in types_seen:
+ raise QAPIExprError(expr_info,
+ "Anonymous union '%s' member '%s' can't "
+ "be distinguished from member '%s'"
+ % (name, key, types_seen[qtype]))
+ types_seen[qtype] = key
+
def check_enum(expr, expr_info):
name = expr['enum']
diff --git a/tests/qapi-schema/alternate-array.err b/tests/qapi-schema/alternate-array.err
index e69de29bb2..8d6ccc7325 100644
--- a/tests/qapi-schema/alternate-array.err
+++ b/tests/qapi-schema/alternate-array.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-array.json:5: Anonymous union 'MyUnion' member 'two' must not be array type
diff --git a/tests/qapi-schema/alternate-array.exit b/tests/qapi-schema/alternate-array.exit
index 573541ac97..d00491fd7e 100644
--- a/tests/qapi-schema/alternate-array.exit
+++ b/tests/qapi-schema/alternate-array.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/alternate-array.json b/tests/qapi-schema/alternate-array.json
index 25224c6c52..0da1a641b3 100644
--- a/tests/qapi-schema/alternate-array.json
+++ b/tests/qapi-schema/alternate-array.json
@@ -1,4 +1,4 @@
-# FIXME: we should not allow array branches in anonymous unions
+# we do not allow array branches in anonymous unions
# TODO: should we support this?
{ 'type': 'One',
'data': { 'name': 'str' } }
diff --git a/tests/qapi-schema/alternate-array.out b/tests/qapi-schema/alternate-array.out
index 90dc22c460..e69de29bb2 100644
--- a/tests/qapi-schema/alternate-array.out
+++ b/tests/qapi-schema/alternate-array.out
@@ -1,4 +0,0 @@
-[OrderedDict([('type', 'One'), ('data', OrderedDict([('name', 'str')]))]),
- OrderedDict([('union', 'MyUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('one', 'One'), ('two', ['int'])]))])]
-[{'enum_name': 'MyUnionKind', 'enum_values': None}]
-[OrderedDict([('type', 'One'), ('data', OrderedDict([('name', 'str')]))])]
diff --git a/tests/qapi-schema/alternate-base.err b/tests/qapi-schema/alternate-base.err
index e69de29bb2..85595b28a6 100644
--- a/tests/qapi-schema/alternate-base.err
+++ b/tests/qapi-schema/alternate-base.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-base.json:4: Union 'MyUnion' must not have a base
diff --git a/tests/qapi-schema/alternate-base.exit b/tests/qapi-schema/alternate-base.exit
index 573541ac97..d00491fd7e 100644
--- a/tests/qapi-schema/alternate-base.exit
+++ b/tests/qapi-schema/alternate-base.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/alternate-base.json b/tests/qapi-schema/alternate-base.json
index 2d36db1835..dad7f02998 100644
--- a/tests/qapi-schema/alternate-base.json
+++ b/tests/qapi-schema/alternate-base.json
@@ -1,4 +1,4 @@
-# FIXME: we should reject anonymous union with base type
+# we reject anonymous union with base type
{ 'type': 'Base',
'data': { 'string': 'str' } }
{ 'union': 'MyUnion',
diff --git a/tests/qapi-schema/alternate-base.out b/tests/qapi-schema/alternate-base.out
index 7fb31f53aa..e69de29bb2 100644
--- a/tests/qapi-schema/alternate-base.out
+++ b/tests/qapi-schema/alternate-base.out
@@ -1,4 +0,0 @@
-[OrderedDict([('type', 'Base'), ('data', OrderedDict([('string', 'str')]))]),
- OrderedDict([('union', 'MyUnion'), ('base', 'Base'), ('discriminator', OrderedDict()), ('data', OrderedDict([('number', 'int')]))])]
-[{'enum_name': 'MyUnionKind', 'enum_values': None}]
-[OrderedDict([('type', 'Base'), ('data', OrderedDict([('string', 'str')]))])]
diff --git a/tests/qapi-schema/alternate-clash.err b/tests/qapi-schema/alternate-clash.err
index e69de29bb2..1130c12834 100644
--- a/tests/qapi-schema/alternate-clash.err
+++ b/tests/qapi-schema/alternate-clash.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-clash.json:2: Union 'Union1' member 'ONE' clashes with 'one'
diff --git a/tests/qapi-schema/alternate-clash.exit b/tests/qapi-schema/alternate-clash.exit
index 573541ac97..d00491fd7e 100644
--- a/tests/qapi-schema/alternate-clash.exit
+++ b/tests/qapi-schema/alternate-clash.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/alternate-clash.json b/tests/qapi-schema/alternate-clash.json
index 7e2ef23f0d..fa2d27ed5e 100644
--- a/tests/qapi-schema/alternate-clash.json
+++ b/tests/qapi-schema/alternate-clash.json
@@ -1,4 +1,4 @@
-# FIXME: we should detect C enum collisions in an anonymous union
+# we detect C enum collisions in an anonymous union
{ 'union': 'Union1',
'discriminator': {},
'data': { 'one': 'str', 'ONE': 'int' } }
diff --git a/tests/qapi-schema/alternate-clash.out b/tests/qapi-schema/alternate-clash.out
index c6687fa98a..e69de29bb2 100644
--- a/tests/qapi-schema/alternate-clash.out
+++ b/tests/qapi-schema/alternate-clash.out
@@ -1,3 +0,0 @@
-[OrderedDict([('union', 'Union1'), ('discriminator', OrderedDict()), ('data', OrderedDict([('one', 'str'), ('ONE', 'int')]))])]
-[{'enum_name': 'Union1Kind', 'enum_values': None}]
-[]
diff --git a/tests/qapi-schema/alternate-conflict-dict.err b/tests/qapi-schema/alternate-conflict-dict.err
index e69de29bb2..2d4550c565 100644
--- a/tests/qapi-schema/alternate-conflict-dict.err
+++ b/tests/qapi-schema/alternate-conflict-dict.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-conflict-dict.json:6: Anonymous union 'MyUnion' member 'two' can't be distinguished from member 'one'
diff --git a/tests/qapi-schema/alternate-conflict-dict.exit b/tests/qapi-schema/alternate-conflict-dict.exit
index 573541ac97..d00491fd7e 100644
--- a/tests/qapi-schema/alternate-conflict-dict.exit
+++ b/tests/qapi-schema/alternate-conflict-dict.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/alternate-conflict-dict.json b/tests/qapi-schema/alternate-conflict-dict.json
index d2ed9de272..ded302edae 100644
--- a/tests/qapi-schema/alternate-conflict-dict.json
+++ b/tests/qapi-schema/alternate-conflict-dict.json
@@ -1,4 +1,4 @@
-# FIXME: we should reject anonymous unions with multiple object branches
+# we reject anonymous unions with multiple object branches
{ 'type': 'One',
'data': { 'name': 'str' } }
{ 'type': 'Two',
diff --git a/tests/qapi-schema/alternate-conflict-dict.out b/tests/qapi-schema/alternate-conflict-dict.out
index b9ac945f5a..e69de29bb2 100644
--- a/tests/qapi-schema/alternate-conflict-dict.out
+++ b/tests/qapi-schema/alternate-conflict-dict.out
@@ -1,6 +0,0 @@
-[OrderedDict([('type', 'One'), ('data', OrderedDict([('name', 'str')]))]),
- OrderedDict([('type', 'Two'), ('data', OrderedDict([('value', 'int')]))]),
- OrderedDict([('union', 'MyUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('one', 'One'), ('two', 'Two')]))])]
-[{'enum_name': 'MyUnionKind', 'enum_values': None}]
-[OrderedDict([('type', 'One'), ('data', OrderedDict([('name', 'str')]))]),
- OrderedDict([('type', 'Two'), ('data', OrderedDict([('value', 'int')]))])]
diff --git a/tests/qapi-schema/alternate-conflict-string.err b/tests/qapi-schema/alternate-conflict-string.err
index e69de29bb2..271ddcdec8 100644
--- a/tests/qapi-schema/alternate-conflict-string.err
+++ b/tests/qapi-schema/alternate-conflict-string.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-conflict-string.json:4: Anonymous union 'MyUnion' member 'two' can't be distinguished from member 'one'
diff --git a/tests/qapi-schema/alternate-conflict-string.exit b/tests/qapi-schema/alternate-conflict-string.exit
index 573541ac97..d00491fd7e 100644
--- a/tests/qapi-schema/alternate-conflict-string.exit
+++ b/tests/qapi-schema/alternate-conflict-string.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/alternate-conflict-string.json b/tests/qapi-schema/alternate-conflict-string.json
index 35245a30e6..3834a3ddfe 100644
--- a/tests/qapi-schema/alternate-conflict-string.json
+++ b/tests/qapi-schema/alternate-conflict-string.json
@@ -1,4 +1,4 @@
-# FIXME: we should reject anonymous unions with multiple string-like branches
+# we reject anonymous unions with multiple string-like branches
{ 'enum': 'Enum',
'data': [ 'hello', 'world' ] }
{ 'union': 'MyUnion',
diff --git a/tests/qapi-schema/alternate-conflict-string.out b/tests/qapi-schema/alternate-conflict-string.out
index e7b39a2117..e69de29bb2 100644
--- a/tests/qapi-schema/alternate-conflict-string.out
+++ b/tests/qapi-schema/alternate-conflict-string.out
@@ -1,5 +0,0 @@
-[OrderedDict([('enum', 'Enum'), ('data', ['hello', 'world'])]),
- OrderedDict([('union', 'MyUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('one', 'str'), ('two', 'Enum')]))])]
-[{'enum_name': 'Enum', 'enum_values': ['hello', 'world']},
- {'enum_name': 'MyUnionKind', 'enum_values': None}]
-[]
diff --git a/tests/qapi-schema/alternate-nested.err b/tests/qapi-schema/alternate-nested.err
index e69de29bb2..59df96e132 100644
--- a/tests/qapi-schema/alternate-nested.err
+++ b/tests/qapi-schema/alternate-nested.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-nested.json:5: Anonymous union 'Union2' member 'nested' has invalid type 'Union1'
diff --git a/tests/qapi-schema/alternate-nested.exit b/tests/qapi-schema/alternate-nested.exit
index 573541ac97..d00491fd7e 100644
--- a/tests/qapi-schema/alternate-nested.exit
+++ b/tests/qapi-schema/alternate-nested.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/alternate-nested.json b/tests/qapi-schema/alternate-nested.json
index d5812bf7ad..ed2b6b7055 100644
--- a/tests/qapi-schema/alternate-nested.json
+++ b/tests/qapi-schema/alternate-nested.json
@@ -1,4 +1,4 @@
-# FIXME: we should reject a nested anonymous union branch
+# we reject a nested anonymous union branch
{ 'union': 'Union1',
'discriminator': {},
'data': { 'name': 'str', 'value': 'int' } }
diff --git a/tests/qapi-schema/alternate-nested.out b/tests/qapi-schema/alternate-nested.out
index 0137c1f984..e69de29bb2 100644
--- a/tests/qapi-schema/alternate-nested.out
+++ b/tests/qapi-schema/alternate-nested.out
@@ -1,5 +0,0 @@
-[OrderedDict([('union', 'Union1'), ('discriminator', OrderedDict()), ('data', OrderedDict([('name', 'str'), ('value', 'int')]))]),
- OrderedDict([('union', 'Union2'), ('discriminator', OrderedDict()), ('data', OrderedDict([('nested', 'Union1')]))])]
-[{'enum_name': 'Union1Kind', 'enum_values': None},
- {'enum_name': 'Union2Kind', 'enum_values': None}]
-[]
diff --git a/tests/qapi-schema/alternate-unknown.err b/tests/qapi-schema/alternate-unknown.err
index e69de29bb2..bf8e9aef64 100644
--- a/tests/qapi-schema/alternate-unknown.err
+++ b/tests/qapi-schema/alternate-unknown.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-unknown.json:2: Anonymous union 'Union' member 'unknown' has invalid type 'MissingType'
diff --git a/tests/qapi-schema/alternate-unknown.exit b/tests/qapi-schema/alternate-unknown.exit
index 573541ac97..d00491fd7e 100644
--- a/tests/qapi-schema/alternate-unknown.exit
+++ b/tests/qapi-schema/alternate-unknown.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/alternate-unknown.json b/tests/qapi-schema/alternate-unknown.json
index 0bab9c2c58..0c305c282c 100644
--- a/tests/qapi-schema/alternate-unknown.json
+++ b/tests/qapi-schema/alternate-unknown.json
@@ -1,4 +1,4 @@
-# FIXME: we should reject an anonymous union with unknown type in branch
+# we reject an anonymous union with unknown type in branch
{ 'union': 'Union',
'discriminator': {},
'data': { 'unknown': 'MissingType' } }
diff --git a/tests/qapi-schema/alternate-unknown.out b/tests/qapi-schema/alternate-unknown.out
index 0911cdc978..e69de29bb2 100644
--- a/tests/qapi-schema/alternate-unknown.out
+++ b/tests/qapi-schema/alternate-unknown.out
@@ -1,3 +0,0 @@
-[OrderedDict([('union', 'Union'), ('discriminator', OrderedDict()), ('data', OrderedDict([('unknown', 'MissingType')]))])]
-[{'enum_name': 'UnionKind', 'enum_values': None}]
-[]
diff --git a/tests/qapi-schema/flat-union-bad-base.err b/tests/qapi-schema/flat-union-bad-base.err
index 5962ff4f74..f9c31b2bf5 100644
--- a/tests/qapi-schema/flat-union-bad-base.err
+++ b/tests/qapi-schema/flat-union-bad-base.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-bad-base.json:9: Base 'OrderedDict([('enum1', 'TestEnum'), ('kind', 'str')])' is not a valid type
+tests/qapi-schema/flat-union-bad-base.json:9: Flat union 'TestUnion' must have a string base field
diff --git a/tests/qapi-schema/flat-union-bad-base.json b/tests/qapi-schema/flat-union-bad-base.json
index 6c141320dc..bb0f02d298 100644
--- a/tests/qapi-schema/flat-union-bad-base.json
+++ b/tests/qapi-schema/flat-union-bad-base.json
@@ -1,4 +1,4 @@
-# FIXME: poor message: we require the base to be an existing complex type
+# we require the base to be an existing complex type
# TODO: should we allow an anonymous inline base type?
{ 'enum': 'TestEnum',
'data': [ 'value1', 'value2' ] }
diff --git a/tests/qapi-schema/flat-union-bad-discriminator.err b/tests/qapi-schema/flat-union-bad-discriminator.err
index e69de29bb2..1661c52b03 100644
--- a/tests/qapi-schema/flat-union-bad-discriminator.err
+++ b/tests/qapi-schema/flat-union-bad-discriminator.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-bad-discriminator.json:10: Flat union 'TestUnion' discriminator must be a string
diff --git a/tests/qapi-schema/flat-union-bad-discriminator.exit b/tests/qapi-schema/flat-union-bad-discriminator.exit
index 573541ac97..d00491fd7e 100644
--- a/tests/qapi-schema/flat-union-bad-discriminator.exit
+++ b/tests/qapi-schema/flat-union-bad-discriminator.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/flat-union-bad-discriminator.json b/tests/qapi-schema/flat-union-bad-discriminator.json
index 1599a59454..3ce43e8356 100644
--- a/tests/qapi-schema/flat-union-bad-discriminator.json
+++ b/tests/qapi-schema/flat-union-bad-discriminator.json
@@ -1,4 +1,4 @@
-# FIXME: we should require the discriminator to be a string naming a base-type member
+# we require the discriminator to be a string naming a base-type member
{ 'enum': 'TestEnum',
'data': [ 'value1', 'value2' ] }
{ 'type': 'TestBase',
diff --git a/tests/qapi-schema/flat-union-bad-discriminator.out b/tests/qapi-schema/flat-union-bad-discriminator.out
index b6ce2171ba..e69de29bb2 100644
--- a/tests/qapi-schema/flat-union-bad-discriminator.out
+++ b/tests/qapi-schema/flat-union-bad-discriminator.out
@@ -1,10 +0,0 @@
-[OrderedDict([('enum', 'TestEnum'), ('data', ['value1', 'value2'])]),
- OrderedDict([('type', 'TestBase'), ('data', OrderedDict([('enum1', 'TestEnum'), ('kind', 'str')]))]),
- OrderedDict([('type', 'TestTypeA'), ('data', OrderedDict([('string', 'str')]))]),
- OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))]),
- OrderedDict([('union', 'TestUnion'), ('base', 'TestBase'), ('discriminator', []), ('data', OrderedDict([('kind1', 'TestTypeA'), ('kind2', 'TestTypeB')]))])]
-[{'enum_name': 'TestEnum', 'enum_values': ['value1', 'value2']},
- {'enum_name': 'TestUnionKind', 'enum_values': None}]
-[OrderedDict([('type', 'TestBase'), ('data', OrderedDict([('enum1', 'TestEnum'), ('kind', 'str')]))]),
- OrderedDict([('type', 'TestTypeA'), ('data', OrderedDict([('string', 'str')]))]),
- OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))])]
diff --git a/tests/qapi-schema/flat-union-inline.err b/tests/qapi-schema/flat-union-inline.err
index 51fbe54350..ec586277b7 100644
--- a/tests/qapi-schema/flat-union-inline.err
+++ b/tests/qapi-schema/flat-union-inline.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-inline.json:7: Base 'OrderedDict([('enum1', 'TestEnum'), ('kind', 'str')])' is not a valid type
+tests/qapi-schema/flat-union-inline.json:7: Flat union 'TestUnion' must have a string base field
diff --git a/tests/qapi-schema/flat-union-inline.json b/tests/qapi-schema/flat-union-inline.json
index 2bdffeb248..f3da1175f8 100644
--- a/tests/qapi-schema/flat-union-inline.json
+++ b/tests/qapi-schema/flat-union-inline.json
@@ -1,4 +1,4 @@
-# FIXME: poor message: we require branches to be a complex type name
+# we require branches to be a complex type name
# TODO: should we allow anonymous inline types?
{ 'enum': 'TestEnum',
'data': [ 'value1', 'value2' ] }
diff --git a/tests/qapi-schema/flat-union-no-base.err b/tests/qapi-schema/flat-union-no-base.err
index 97323a0432..bb3f708747 100644
--- a/tests/qapi-schema/flat-union-no-base.err
+++ b/tests/qapi-schema/flat-union-no-base.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-no-base.json:9: Flat union 'TestUnion' must have a base field
+tests/qapi-schema/flat-union-no-base.json:9: Flat union 'TestUnion' must have a string base field
diff --git a/tests/qapi-schema/flat-union-no-base.json b/tests/qapi-schema/flat-union-no-base.json
index 08a02476a3..9547bb8988 100644
--- a/tests/qapi-schema/flat-union-no-base.json
+++ b/tests/qapi-schema/flat-union-no-base.json
@@ -1,4 +1,4 @@
-# FIXME: flat unions should require a base
+# flat unions require a base
# TODO: simple unions should be able to use an enum discriminator
{ 'type': 'TestTypeA',
'data': { 'string': 'str' } }
diff --git a/tests/qapi-schema/union-bad-branch.err b/tests/qapi-schema/union-bad-branch.err
index e69de29bb2..8822735561 100644
--- a/tests/qapi-schema/union-bad-branch.err
+++ b/tests/qapi-schema/union-bad-branch.err
@@ -0,0 +1 @@
+tests/qapi-schema/union-bad-branch.json:6: Union 'MyUnion' member 'ONE' clashes with 'one'
diff --git a/tests/qapi-schema/union-bad-branch.exit b/tests/qapi-schema/union-bad-branch.exit
index 573541ac97..d00491fd7e 100644
--- a/tests/qapi-schema/union-bad-branch.exit
+++ b/tests/qapi-schema/union-bad-branch.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/union-bad-branch.json b/tests/qapi-schema/union-bad-branch.json
index 11e46de565..4303666bb5 100644
--- a/tests/qapi-schema/union-bad-branch.json
+++ b/tests/qapi-schema/union-bad-branch.json
@@ -1,4 +1,4 @@
-# FIXME: we should reject normal unions where branches would collide in C
+# we reject normal unions where branches would collide in C
{ 'type': 'One',
'data': { 'string': 'str' } }
{ 'type': 'Two',
diff --git a/tests/qapi-schema/union-bad-branch.out b/tests/qapi-schema/union-bad-branch.out
index 6baf01be79..e69de29bb2 100644
--- a/tests/qapi-schema/union-bad-branch.out
+++ b/tests/qapi-schema/union-bad-branch.out
@@ -1,6 +0,0 @@
-[OrderedDict([('type', 'One'), ('data', OrderedDict([('string', 'str')]))]),
- OrderedDict([('type', 'Two'), ('data', OrderedDict([('number', 'int')]))]),
- OrderedDict([('union', 'MyUnion'), ('data', OrderedDict([('one', 'One'), ('ONE', 'Two')]))])]
-[{'enum_name': 'MyUnionKind', 'enum_values': None}]
-[OrderedDict([('type', 'One'), ('data', OrderedDict([('string', 'str')]))]),
- OrderedDict([('type', 'Two'), ('data', OrderedDict([('number', 'int')]))])]
diff --git a/tests/qapi-schema/union-max.err b/tests/qapi-schema/union-max.err
index e69de29bb2..55ce4399d6 100644
--- a/tests/qapi-schema/union-max.err
+++ b/tests/qapi-schema/union-max.err
@@ -0,0 +1 @@
+tests/qapi-schema/union-max.json:2: Union 'Union' member 'max' clashes with '(automatic)'
diff --git a/tests/qapi-schema/union-max.exit b/tests/qapi-schema/union-max.exit
index 573541ac97..d00491fd7e 100644
--- a/tests/qapi-schema/union-max.exit
+++ b/tests/qapi-schema/union-max.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/union-max.json b/tests/qapi-schema/union-max.json
index 45648c474b..d6ad986999 100644
--- a/tests/qapi-schema/union-max.json
+++ b/tests/qapi-schema/union-max.json
@@ -1,3 +1,3 @@
-# FIXME: we should reject 'max' branch in a union, for collision with C enum
+# we reject 'max' branch in a union, for collision with C enum
{ 'union': 'Union',
'data': { 'max': 'int' } }
diff --git a/tests/qapi-schema/union-max.out b/tests/qapi-schema/union-max.out
index 2757d367f0..e69de29bb2 100644
--- a/tests/qapi-schema/union-max.out
+++ b/tests/qapi-schema/union-max.out
@@ -1,3 +0,0 @@
-[OrderedDict([('union', 'Union'), ('data', OrderedDict([('max', 'int')]))])]
-[{'enum_name': 'UnionKind', 'enum_values': None}]
-[]