shithub: mc

Download patch

ref: 311adc5c21b028429114abd30aa19ef940519265
parent: 4dc63d86d200712bb4b2c38629a90356d45fd0f2
author: Ori Bernstein <[email protected]>
date: Mon Aug 4 16:03:05 EDT 2014

Add proper checking for types with parameters.

--- a/parse/type.c
+++ b/parse/type.c
@@ -297,6 +297,11 @@
 
     if (t->type != Tyname && t->type != Tyunres)
         return 0;
+    /*
+    if we have no arguments passed in, and we have parameters
+    we have a type of the form
+    type t(@a,...) = ...
+     */
     if (!t->narg)
         return t->nparam > 0;
     else
@@ -310,19 +315,44 @@
  * Checks if a type contains any type
  * parameers at all (ie, if it generic).
  */
-int hasparams(Type *t)
+int hasparamsrec(Type *t, Bitset *visited)
 {
     size_t i;
 
-    if (t->type == Typaram || isgeneric(t))
-        return 1;
-    for (i = 0; i < t->nsub; i++)
-        if (hasparams(t->sub[i]))
+    switch (t->type) {
+        case Typaram:
             return 1;
-    for (i = 0; i < t->narg; i++)
-        if (hasparams(t->arg[i]))
-            return 1;
+        case Tyname:
+        case Tyunres:
+            return isgeneric(t);
+        case Tystruct:
+            for (i = 0; i < t->nmemb; i++)
+                if (hasparamsrec(t->sdecls[i]->decl.type, visited))
+                    return 1;
+            break;
+        case Tyunion:
+            for (i = 0; i < t->nmemb; i++)
+                if (t->udecls[i]->etype && hasparamsrec(t->udecls[i]->etype, visited))
+                    return 1;
+            break;
+        default:
+            for (i = 0; i < t->nsub; i++)
+                if (hasparams(t->sub[i]))
+                    return 1;
+            break;
+    }
     return 0;
+}
+
+int hasparams(Type *t)
+{
+    Bitset *visited;
+    int r;
+
+    visited = mkbs();
+    r = hasparamsrec(t, visited);
+    bsfree(visited);
+    return r;
 }
 
 Type *tybase(Type *t)