_cairo_surface_is_snapshot() return error result on armcc on RVDS/MDK
Submitted by Zunfeng Chen
Assigned to Chris Wilson @ickle
Description
static inline cairo_bool_t _cairo_surface_is_snapshot (cairo_surface_t *surface) { return surface->backend->type == (cairo_surface_type_t)CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT; }
On some platforms or compilers, size of enumuration types may be refered to the max value of them, to reduce the memory usage. Like armcc of RVDS/MDK.
The detail on the armcc:
All the enum values of cairo_surface_type_t are small than 255, so the variable defined by cairo_surface_type_t only has 1 bytes on the memory stack, but CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT = 0x1000, so it has two bytes.
The code snippet from cairo-surface-snapshort-inline.h (above), comparation between cairo_surface_type_t and cairo_internal_surface_type_t, CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT is casted to cairo_surface_type_t, the value may be wrong. Because not every compiler treates enumuration type as int.
Because of this, image surface crashed on arm cpu which is not running any OS.
There are too many code snippets cast a enumuration type to another one, this may be not a good idea. ARMCC of RVDS/MDK gave me too many warning about the issue.
I think there are not many persons run cairo on the bear metal without OS, but it it indeed a problem.
The fixed code snippet that I've done is below:
static inline cairo_bool_t _cairo_surface_is_snapshot (cairo_surface_t *surface) { return (int)surface->backend->type == (int)CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT; }