qapi: Don't cast Enum* to int*
C compilers are allowed to represent enums as a smaller type
than int, if all enum values fit in the smaller type. There
are even compiler flags that force the use of this smaller
representation, although using them changes the ABI of a
binary. Therefore, our generated code for visit_type_ENUM()
(for all qapi enums) was wrong for casting Enum* to int* when
calling visit_type_enum().
It appears that no one has been using compiler ABI switches
for qemu, because if they had, we are potentially dereferencing
beyond bounds or even risking a SIGBUS on platforms where
unaligned pointer dereferencing is fatal. But it is still
better to avoid the practice entirely, and just use the correct
types.
This matches the fix for alternate qapi types, done earlier in
commit 0426d53
"qapi: Simplify visiting of alternate types",
with generated code changing as:
| void visit_type_QType(Visitor *v, QType *obj, const char *name, Error **errp)
| {
|- visit_type_enum(v, (int *)obj, QType_lookup, "QType", name, errp);
|+ int value = *obj;
|+ visit_type_enum(v, &value, QType_lookup, "QType", name, errp);
|+ *obj = value;
| }
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <1454075341-13658-17-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
04e070d217
commit
395a233f7c
@ -178,12 +178,13 @@ out:
|
|||||||
|
|
||||||
|
|
||||||
def gen_visit_enum(name):
|
def gen_visit_enum(name):
|
||||||
# FIXME cast from enum *obj to int * invalidly assumes enum is int
|
|
||||||
return mcgen('''
|
return mcgen('''
|
||||||
|
|
||||||
void visit_type_%(c_name)s(Visitor *v, %(c_name)s *obj, const char *name, Error **errp)
|
void visit_type_%(c_name)s(Visitor *v, %(c_name)s *obj, const char *name, Error **errp)
|
||||||
{
|
{
|
||||||
visit_type_enum(v, (int *)obj, %(c_name)s_lookup, "%(name)s", name, errp);
|
int value = *obj;
|
||||||
|
visit_type_enum(v, &value, %(c_name)s_lookup, "%(name)s", name, errp);
|
||||||
|
*obj = value;
|
||||||
}
|
}
|
||||||
''',
|
''',
|
||||||
c_name=c_name(name), name=name)
|
c_name=c_name(name), name=name)
|
||||||
|
Loading…
Reference in New Issue
Block a user