diff options
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | girepository/giroffsets.c | 83 | ||||
-rwxr-xr-x | tests/offsets/gen-gitestoffsets | 2 | ||||
-rw-r--r-- | tests/offsets/offsets.h | 14 |
4 files changed, 92 insertions, 28 deletions
@@ -1,4 +1,23 @@ -2009-01-28 Johan Bilien <jobi@via.ecp.fr> +2009-02-02 Andreas Rottmann <a.rottmann@gmx.at> + + Bug 563469 – Arrays not treated correctly in struct offset calculation + + * tests/offsets/offsets.h (OffsetsArray): New struct, containing a + bunch of arrays. + + * tests/offsets/gen-gitestoffsets (FIELD_RE): Handle arrays. + + * girepository/giroffsets.c (get_interface_size_alignment): + Refactored to make it more general, now takes a GIrNodeType* + instead of a GIrNodeField*, plus an additional 'who' parameter + that denotes what the size/alignment is calculated for. + (get_type_size_alignment): New function, refactored version of + get_field_size_alignment(). + (get_field_size_alignment): Implemented in terms of + get_type_size_alignment(). + (get_type_size_alignment): Handle array types correctly. + + 2009-01-28 Johan Bilien <jobi@via.ecp.fr> * tests/scanner/annotation-1.0-expected.gir: add missing with_voidp diff --git a/girepository/giroffsets.c b/girepository/giroffsets.c index 46cdbd90..f224e693 100644 --- a/girepository/giroffsets.c +++ b/girepository/giroffsets.c @@ -144,21 +144,19 @@ get_enum_size_alignment (GIrNodeEnum *enum_node, } static gboolean -get_interface_size_alignment (GIrNodeField *field, - GIrNode *parent_node, - GIrModule *module, - GList *modules, - gint *size, - gint *alignment) +get_interface_size_alignment (GIrNodeType *type, + GIrModule *module, + GList *modules, + gint *size, + gint *alignment, + const char *who) { - GIrNodeType *type = field->type; GIrNode *iface; GIrModule *iface_module; if (!g_ir_find_node (module, modules, type->interface, &iface, &iface_module)) { - g_warning ("Can't resolve type '%s' for field %s.%s.%s", - type->interface, module->name, parent_node->name, ((GIrNode *)field)->name); + g_warning ("Can't resolve type '%s' for %s", type->interface, who); *size = -1; *alignment = -1; return FALSE; @@ -212,8 +210,8 @@ get_interface_size_alignment (GIrNodeField *field, } default: { - g_warning ("Field %s.%s.%s has is not a pointer and is of type %s", - module->name, parent_node->name, ((GIrNode *)field)->name, + g_warning ("%s has is not a pointer and is of type %s", + who, g_ir_node_type_to_string (iface->type)); *size = -1; *alignment = -1; @@ -225,17 +223,34 @@ get_interface_size_alignment (GIrNodeField *field, } static gboolean -get_field_size_alignment (GIrNodeField *field, - GIrNode *parent_node, - GIrModule *module, - GList *modules, - gint *size, - gint *alignment) +get_type_size_alignment (GIrNodeType *type, + GIrModule *module, + GList *modules, + gint *size, + gint *alignment, + const char *who) { - GIrNodeType *type = field->type; ffi_type *type_ffi; - if (type->is_pointer) + if (type->tag == GI_TYPE_TAG_ARRAY) + { + gint elt_size, elt_alignment; + + if (!type->has_size + || !get_type_size_alignment(type->parameter_type1, module, modules, + &elt_size, &elt_alignment, who)) + { + *size = -1; + *alignment = -1; + return FALSE; + } + + *size = type->size * elt_size; + *alignment = elt_alignment; + + return TRUE; + } + else if (type->is_pointer) { type_ffi = &ffi_type_pointer; } @@ -243,9 +258,7 @@ get_field_size_alignment (GIrNodeField *field, { if (type->tag == GI_TYPE_TAG_INTERFACE) { - return get_interface_size_alignment (field, parent_node, - module, modules, - size, alignment); + return get_interface_size_alignment (type, module, modules, size, alignment, who); } else { @@ -253,16 +266,15 @@ get_field_size_alignment (GIrNodeField *field, if (type_ffi == &ffi_type_void) { - g_warning ("Field %s.%s.%s has void type", - module->name, parent_node->name, ((GIrNode *)field)->name); + g_warning ("%s has void type", who); *size = -1; *alignment = -1; return FALSE; } else if (type_ffi == &ffi_type_pointer) { - g_warning ("Field %s.%s.%s has is not a pointer and is of type %s", - module->name, parent_node->name, ((GIrNode *)field)->name, + g_warning ("%s has is not a pointer and is of type %s", + who, g_type_tag_to_string (type->tag)); *size = -1; *alignment = -1; @@ -278,6 +290,25 @@ get_field_size_alignment (GIrNodeField *field, return TRUE; } +static gboolean +get_field_size_alignment (GIrNodeField *field, + GIrNode *parent_node, + GIrModule *module, + GList *modules, + gint *size, + gint *alignment) +{ + gchar *who; + gboolean success; + + who = g_strdup_printf ("field %s.%s.%s", module->name, parent_node->name, ((GIrNode *)field)->name); + + success = get_type_size_alignment (field->type, module, modules, size, alignment, who); + g_free (who); + + return success; +} + #define ALIGN(n, align) (((n) + (align) - 1) & ~((align) - 1)) static gboolean diff --git a/tests/offsets/gen-gitestoffsets b/tests/offsets/gen-gitestoffsets index ce4a977c..58139fc2 100755 --- a/tests/offsets/gen-gitestoffsets +++ b/tests/offsets/gen-gitestoffsets @@ -61,7 +61,7 @@ STRUCT_DEF_RE = compile_re("struct\s+_(TOKEN)\s*{([^}]*)}") # This certainly can't handle all type declarations, but it only # needs to handle the ones we use in the test cases -FIELD_RE = compile_re("^(?:const\s+)?TOKEN(?:[\s*]+)(TOKEN)\s*;$"); +FIELD_RE = compile_re(r"^(?:const\s+)?TOKEN(?:[\s*]+)(TOKEN)\s*(?:\[([0-9]*)\])?\s*;$") input_f = open(sys.argv[1]) diff --git a/tests/offsets/offsets.h b/tests/offsets/offsets.h index c0edfe01..9c29a989 100644 --- a/tests/offsets/offsets.h +++ b/tests/offsets/offsets.h @@ -104,4 +104,18 @@ struct _OffsetsNested { char dummy3; }; +/* Test array offsets + */ + +typedef struct _OffsetsArray OffsetsArray; + +struct _OffsetsArray +{ + gint some_ints[2]; + gint8 some_int8s[3]; + gdouble some_doubles[4]; + Enum1 some_enum[2]; + gpointer some_ptrs[5]; +}; + #endif /* __OFFSETS_H__ */ |