Fail gracefully with an informative error message when recursion is
authorOwen Taylor <otaylor@redhat.com>
Tue, 11 Nov 2008 13:45:13 +0000 (13:45 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Tue, 11 Nov 2008 13:45:13 +0000 (13:45 +0000)
2008-11-11  Owen Taylor  <otaylor@redhat.com>

        * girepository/giroffsets.c: Fail gracefully with an informative
        error message when recursion is encountered when computing a
        structure size.

svn path=/trunk/; revision=882

ChangeLog
girepository/giroffsets.c

index d6a83cb..826dae0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-11-11  Owen Taylor  <otaylor@redhat.com>
+
+       * girepository/giroffsets.c: Fail gracefully with an informative
+       error message when recursion is encountered when computing a 
+       structure size.
+
 2008-11-11  Owen Taylor  <otaylor@redhat.com>
 
        * girepository/girparser.c: Remove an unused variable.
index 8489dc4..f78e479 100644 (file)
@@ -176,7 +176,7 @@ get_interface_size_alignment (GIrNodeType *type,
       }
     }
 
-  return *alignment != -1;
+  return *alignment > 0;
 }
 
 static gboolean
@@ -245,6 +245,8 @@ compute_struct_field_offsets (GList       *members,
   GList *l;
   gboolean have_error = FALSE;
 
+  *alignment_out = -2; /* mark to detect recursion */
+
   for (l = members; l; l = l->next)
     {
       GIrNode *member = (GIrNode *)l->data;
@@ -310,6 +312,8 @@ compute_union_field_offsets (GList       *members,
   GList *l;
   gboolean have_error = FALSE;
 
+  *alignment_out = -2; /* mark to detect recursion */
+
   for (l = members; l; l = l->next)
     {
       GIrNode *member = (GIrNode *)l->data;
@@ -353,6 +357,26 @@ compute_union_field_offsets (GList       *members,
   return !have_error;
 }
 
+static gboolean
+check_needs_computation (GIrNode   *node,
+                        GIrModule *module,
+                        gint       alignment)
+{
+  /*
+   *  0: Not yet computed
+   * >0: Previously succeeded
+   * -1: Previously failed
+   * -2: In progress
+   */
+  if (alignment == -2)
+    {
+      g_warning ("Recursion encountered when computing the size of %s.%s",
+                module->name, node->name);
+    }
+
+  return alignment == 0;
+}
+
 /**
  * g_ir_node_compute_offsets:
  * @node: a #GIrNode
@@ -366,7 +390,7 @@ compute_union_field_offsets (GList       *members,
 void
 g_ir_node_compute_offsets (GIrNode   *node,
                           GIrModule *module,
-                  GList     *modules)
+                          GList     *modules)
 {
   switch (node->type)
     {
@@ -374,7 +398,7 @@ g_ir_node_compute_offsets (GIrNode   *node,
       {
        GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
 
-       if (boxed->alignment != 0) /* Already done */
+       if (!check_needs_computation (node, module, boxed->alignment))
          return;
 
        compute_struct_field_offsets (boxed->members,
@@ -386,7 +410,7 @@ g_ir_node_compute_offsets (GIrNode   *node,
       {
        GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
 
-       if (struct_->alignment != 0)
+       if (!check_needs_computation (node, module, struct_->alignment))
          return;
 
        compute_struct_field_offsets (struct_->members,
@@ -398,7 +422,7 @@ g_ir_node_compute_offsets (GIrNode   *node,
       {
        GIrNodeUnion *union_ = (GIrNodeUnion *)node;
 
-       if (union_->alignment != 0)
+       if (!check_needs_computation (node, module, union_->alignment))
          return;
 
        compute_union_field_offsets (union_->members,