Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Walters <walters@src.gnome.org>2009-02-02 16:31:02 (GMT)
committer Colin Walters <walters@src.gnome.org>2009-02-02 16:31:02 (GMT)
commit34c6fe51cd8d669d95aef52bda9abbc38257bca9 (patch)
tree3785e49132f0f2cc0e536d3a677da746f56ba85a
parentf9a260e02e9921149d52622778ae7c489a5fa257 (diff)
Bug 563469 – Arrays not treated correctly in struct offset calculation
Arrays are currently not handled specially, and hence treated as pointers in giroffsets.c:get_field_size_alignment(), which is (obviously) wrong. svn path=/trunk/; revision=1078
-rw-r--r--ChangeLog21
-rw-r--r--girepository/giroffsets.c83
-rwxr-xr-xtests/offsets/gen-gitestoffsets2
-rw-r--r--tests/offsets/offsets.h14
4 files changed, 92 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index e3a418c..8f1b793 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 46cdbd9..f224e69 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 ce4a977..58139fc 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 c0edfe0..9c29a98 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__ */