widl: Fix a crash in compare_expr.

Dan Hipschman dsh at linux.ucla.edu
Wed Oct 24 20:06:16 CDT 2007


This patch fixes a crash when generating a proxy for oleidl.idl.  The
problem is that compare_expr assumes that sizeof keeps some sort of
information in expr->ref, which it doesn't (widl currently doesn't
handle sizeof(expr), only sizeof(type)).  Hence we need to have a way
to compare types.  This is actually a lot of work because there are so
many ways the types can differ (weird attributes, mostly), so I prefer
to punt on it at the moment.  This at least fixes the crash, and the
only use of compare_expr is to avoid spitting out multiple evaluation
routines in write_conf_or_var_desc; so it's basically just an
optimization.  For oleidl.idl it's good enough that it only produces
one evaluation callback.  (I should note that there's another bug that
results in widl not generating evaluation callbacks for proxy files at
all, so if you test that theory you won't get the same result.
However, I've got another patch I'll send tomorrow or Friday that
fixes that separate problem.)  With this patch, widl will generate a
proxy for oleidl.idl.  It should be useful for fixing
http://bugs.winehq.org/show_bug.cgi?id=7026 .

---
 tools/widl/typegen.c |   25 +++++++++++++++++++++++--
 1 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 9dcffa7..f6d5536 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -228,6 +228,22 @@ static const char *get_context_handle_type_name(const type_t *type)
     return NULL;
 }
 
+/* This is actually fairly involved to implement precisely, due to the
+   effects attributes may have and things like that.  Right now this is
+   only used for optimization, so just check for a very small set of
+   criteria that guarantee the types are equivalent; assume every thing
+   else is different.   */
+static int compare_type(const type_t *a, const type_t *b)
+{
+    if (a == b
+        || (a->name
+            && b->name
+            && strcmp(a->name, b->name) == 0))
+        return 0;
+    /* Ordering doesn't need to be implemented yet.  */
+    return 1;
+}
+
 static int compare_expr(const expr_t *a, const expr_t *b)
 {
     int ret;
@@ -265,12 +281,17 @@ static int compare_expr(const expr_t *a, const expr_t *b)
             if (ret != 0)
                 return ret;
             return compare_expr(a->u.ext, b->u.ext);
+        case EXPR_CAST:
+            ret = compare_type(a->u.tref, b->u.tref);
+            if (ret != 0)
+                return ret;
+            /* Fall through.  */
         case EXPR_NOT:
         case EXPR_NEG:
         case EXPR_PPTR:
-        case EXPR_CAST:
-        case EXPR_SIZEOF:
             return compare_expr(a->ref, b->ref);
+        case EXPR_SIZEOF:
+            return compare_type(a->u.tref, b->u.tref);
         case EXPR_VOID:
             return 0;
     }



More information about the wine-patches mailing list