]> andersk Git - splint.git/blobdiff - src/ctbase.i
Made allocations involving sizeof work correctly (test/malloc.c).
[splint.git] / src / ctbase.i
index 53c663364e84a38d8a88a40fcb7154b86875da41..c59eb7628313015a9b5de658abda9405dca3db3c 100644 (file)
@@ -1,36 +1,48 @@
 /* ;-*-C-*-; 
-** Copyright (c) Massachusetts Institute of Technology 1994-1998.
-**          All Rights Reserved.
-**          Unpublished rights reserved under the copyright laws of
-**          the United States.
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2003 University of Virginia,
+**         Massachusetts Institute of Technology
 **
-** THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
-** OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2 of the License, or (at your
+** option) any later version.
+** 
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+** General Public License for more details.
+** 
+** The GNU General Public License is available from http://www.gnu.org/ or
+** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+** MA 02111-1307, USA.
 **
-** This code is distributed freely and may be used freely under the 
-** following conditions:
-**
-**     1. This notice may not be removed or altered.
-**
-**     2. Works derived from this code are not distributed for
-**        commercial gain without explicit permission from MIT 
-**        (for permission contact lclint-request@sds.lcs.mit.edu).
+** For information on splint: splint@cs.virginia.edu
+** To report a bug: splint-bug@cs.virginia.edu
+** For more information: http://www.splint.org
 */
 /*
 ** ctbase.i
 **
 ** NOTE: This is not a stand-alone source file, but is included in ctype.c.
-**       (This is necessary becuase there is no other way in C to have a
+**       (This is necessary because there is no other way in C to have a
 **       hidden scope, besides at the file level.)
 */
 
 /*@access cprim*/
 
-typedef /*@null@*/ struct __ctbase *ctbase;
+abst_typedef /*@null@*/ struct s_ctbase *ctbase;
+
+/*@function static bool ctuid_isAnyUserType (sef ctuid p_cid) @*/
 
-typedef struct _ctentry {
+/*@-macrofcndecl@*/ /*@-macroparams@*/
+# define ctuid_isAnyUserType(cid) \
+   ((cid) == CT_ABST || (cid) == CT_USER || (cid) == CT_NUMABST)
+/*@=macrofcndecl@*/ /*@=macroparams@*/
+
+/*:private:*/ typedef struct {
   ctkind kind;
-  ctbase ctbase;
+  ctbase ctbase; 
   ctype base;     /* type I point to (or element of array) */
   ctype ptr;     /* type of pointer to me */
   ctype array;    /* type of array of me */
@@ -39,7 +51,7 @@ typedef struct _ctentry {
 
 typedef /*@only@*/ ctentry o_ctentry;
           
-typedef struct _cttable {
+typedef struct {
   int size;
   int nspace;
   /*@relnull@*/ /*@only@*/ o_ctentry *entries;
@@ -53,6 +65,7 @@ extern bool ctentry_isBogus (/*@sef@*/ ctentry p_c) /*@*/;
 static cttable cttab = { 0, 0, NULL };
 
 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createAbstract (typeId p_u);
+static /*@notnull@*/ /*@only@*/ ctbase ctbase_createNumAbstract (typeId p_u);
 static /*@observer@*/ cstring ctentry_doUnparse (ctentry p_c) /*@modifies p_c@*/;
 static /*@only@*/ ctentry
   ctentry_make (ctkind p_ctk, /*@keep@*/ ctbase p_c, ctype p_base, 
@@ -64,7 +77,8 @@ static void cttable_grow (void);
 static ctype cttable_addDerived (ctkind p_ctk, /*@keep@*/ ctbase p_cnew, ctype p_base);
 static ctype cttable_addFull (/*@keep@*/ ctentry p_cnew);
 static bool ctentry_isInteresting (ctentry p_c) /*@*/;
-static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeFixedArray (ctype p_b, long p_size) /*@*/ ;
+static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeFixedArray (ctype p_b, size_t p_size) /*@*/ ;
+static bool ctbase_isAnytype (/*@notnull@*/ ctbase p_b) /*@*/ ;
 
 /* 
 ** These are file-static macros (used in ctype.c).  No way to
@@ -120,8 +134,6 @@ static /*@notnull@*/ /*@only@*/ ctbase ctbase_makePointer (ctype p_b) /*@*/ ;
 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeArray (ctype p_b) /*@*/ ;
 static /*@notnull@*/ ctype 
   ctbase_makeFunction (ctype p_b, /*@only@*/ uentryList p_p) /*@*/ ;
-static /*@notnull@*/ /*@only@*/ ctbase 
-  ctbase_makeRealFunction (ctype p_b, /*@dependent@*/ uentryList p_p) /*@*/ ;
 static /*@notnull@*/ /*@observer@*/ ctbase 
   ctbase_realFunction (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
 static ctype ctbase_baseArrayPtr (/*@notnull@*/ ctbase p_c) /*@*/ ;
@@ -137,39 +149,38 @@ extern int cttable_lastIndex();
 # define cttable_lastIndex()  (cttab.size - 1)
 /*@=macroundef@*/
 
-typedef struct _cfcn
+typedef struct
 {
   ctype rval;
-  /*@dependent@*/ uentryList params;  /* params are owned if liveparams is TRUE */
-  bool liveparams;
+  /*@only@*/ uentryList params; 
 } *cfcn; 
 
-typedef struct _tsu
+typedef struct
 {
   cstring   name;
   uentryList fields;
 } *tsu;
 
-typedef struct _tconj
+typedef struct
 {
   ctype a;
   ctype b;
   bool  isExplicit;
 } *tconj;
 
-typedef struct _tenum
+typedef struct
 {
   cstring      tag;
   enumNameList members;
 } *tenum;
 
-typedef struct _tfixed
+typedef struct
 {
   ctype base;
-  long size;
+  size_t size;
 } *tfixed;
  
-typedef union _uconts
+typedef union 
 {
   cprim         prim;      /* primitive */
   typeId        tid;       /* abstract, user */
@@ -181,7 +192,7 @@ typedef union _uconts
   tfixed        farray;    /* fixed array */
 } uconts;
 
-struct __ctbase
+struct s_ctbase
 {
   ctuid    type;
   uconts   contents;
@@ -275,7 +286,7 @@ static bool ctuid_isAP (ctuid c) /*@*/
 
 static typeId ctbase_typeId (ctbase p_c);
 static /*@only@*/ cstring ctbase_dump (ctbase p_c);
-static /*@only@*/ ctbase ctbase_undump (char **p_c);
+static /*@only@*/ ctbase ctbase_undump (char **p_c) /*@requires maxRead(*p_c) >= 2 @*/;
 static int ctbase_compare (ctbase p_c1, ctbase p_c2, bool p_strict);
 static bool ctbase_matchArg (ctbase p_c1, ctbase p_c2);
 static /*@notnull@*/ /*@only@*/ ctbase 
@@ -286,8 +297,8 @@ static bool ctbase_isExplicitConj (/*@notnull@*/ ctbase p_c) /*@*/ ;
 static bool ctbase_forceMatch (ctbase p_c1, ctbase p_c2) /*@modifies p_c1, p_c2@*/ ;
 static /*@notnull@*/ /*@only@*/ ctbase ctbase_expectFunction (ctype p_c);
 static bool ctbase_isVoidPointer(/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
-static bool ctbase_isUnion (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
-static bool ctbase_isStruct (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
+static bool ctbase_isUnion (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
+static bool ctbase_isStruct (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
 static /*@observer@*/ cstring ctbase_enumTag (/*@notnull@*/ ctbase p_ct) /*@*/ ;
 static /*@only@*/ cstring ctbase_unparseNotypes (ctbase p_c) /*@*/ ;
 
@@ -295,7 +306,14 @@ static /*@out@*/ /*@notnull@*/ /*@only@*/ ctbase ctbase_new (void) /*@*/ ;
 static int nctbases = 0;
 
 static /*@notnull@*/ /*@only@*/ 
-  ctbase ctbase_makeLiveFunction (ctype p_b, /*@owned@*/ uentryList p_p);
+  ctbase ctbase_makeLiveFunction (ctype p_b, /*@only@*/ uentryList p_p);
+
+static bool ctbase_isUnnamedSU (ctbase c)
+{
+  return (ctbase_isDefined (c)
+         && (ctbase_isStruct (c) || ctbase_isUnion (c))
+         && isFakeTag (c->contents.su->name));
+}
 
 static /*@observer@*/ ctbase ctbase_realType (ctbase c)
 {
@@ -365,7 +383,7 @@ ctbase_isStruct (/*@notnull@*/ ctbase c)
 }
 
 static bool
-ctbase_isUnion (/*@notnull@*/ /*@dependent@*/ ctbase c)
+ctbase_isUnion (/*@notnull@*/ ctbase c)
 {
   ctbase r = ctbase_realType (c);
 
@@ -389,7 +407,7 @@ ctbase_typeBaseUid (ctbase c)
        {
          return ctbase_typeBaseUid (ctype_getCtbase (c->contents.base));
        }
-      else if (ct == CT_USER || ct == CT_ABST)
+      else if (ct == CT_USER || ct == CT_ABST || ct == CT_NUMABST)
        {
          return c->contents.tid;
        }
@@ -424,7 +442,7 @@ ctbase_isBaseUA (ctbase c)
          return ctbase_isBaseUA (ctype_getCtbase (c->contents.farray->base));
        }
       else
-       return (ct == CT_USER || ct == CT_ABST);
+       return (ct == CT_USER || ct == CT_ABST || ct == CT_NUMABST);
     }
   return FALSE;
 }
@@ -438,8 +456,15 @@ ctbase_typeId (ctbase c)
     }
   else
     {
-      llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
-      return typeId_invalid;
+      if (ctbase_isConj (c)) 
+       {
+         return ctbase_typeId (ctype_getCtbase (ctbase_getConjA (c)));
+       }
+      else
+       {
+         llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
+         return typeId_invalid;
+       }
     }
 }
 
@@ -459,8 +484,8 @@ ctbase_unparse (ctbase c)
     case CT_PRIM:
       return (cprim_unparse (c->contents.prim));
     case CT_USER:
-      return (usymtab_getTypeEntryName (c->contents.tid));
     case CT_ABST:
+    case CT_NUMABST:
       return (usymtab_getTypeEntryName (c->contents.tid));
     case CT_EXPFCN:
       return (message ("<expf: %t>", c->contents.base));
@@ -476,7 +501,8 @@ ctbase_unparse (ctbase c)
          return (message ("%t *", c->contents.base));
        }
     case CT_FIXEDARRAY:
-      return (message ("%t [%d]", c->contents.farray->base, 
+      return (message ("%t [%d]", 
+                      c->contents.farray->base, 
                       (int) c->contents.farray->size));
     case CT_ARRAY:
       return (message ("%t []", c->contents.base));
@@ -493,7 +519,8 @@ ctbase_unparse (ctbase c)
        }
       else
        {
-         return (message ("struct { %q }", uentryList_unparseAbbrev (c->contents.su->fields)));
+         return (message ("struct { %q }", 
+                          uentryList_unparseAbbrev (c->contents.su->fields))); 
        }
     case CT_UNION:
       if (cstring_isDefined (c->contents.su->name) &&
@@ -520,7 +547,11 @@ ctbase_unparse (ctbase c)
                           enumNameList_unparseBrief (c->contents.cenum->members)));
        }
     case CT_CONJ:
-      if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
+      if (ctbase_isAnytype (c))
+       {
+         return (cstring_makeLiteral ("<any>"));
+       }
+      else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
        {
          if (!ctype_isSimple (c->contents.conj->a) ||
              !ctype_isSimple (c->contents.conj->b))
@@ -570,8 +601,8 @@ static /*@only@*/ cstring
                           enumNameList_unparse (c->contents.cenum->members)));
        }
     case CT_USER:
-      return (usymtab_getTypeEntryName (c->contents.tid));
     case CT_ABST:
+    case CT_NUMABST:
       return (usymtab_getTypeEntryName (c->contents.tid));
     case CT_EXPFCN:
       return (message ("<expf: %t>", c->contents.base));
@@ -591,7 +622,14 @@ static /*@only@*/ cstring
     case CT_UNION:
       return (message ("union %s { ... }", c->contents.su->name));
     case CT_CONJ:
-      return (message ("%t", c->contents.conj->a));
+      if (ctbase_isAnytype (c))
+       {
+         return (cstring_makeLiteral ("<any>"));
+       }
+      else
+       {
+         return (message ("%t", c->contents.conj->a));
+       }
     BADDEFAULT;
     }
   BADEXIT;
@@ -623,6 +661,8 @@ ctbase_unparseNotypes (ctbase c)
       return (message ("uT#%d", c->contents.tid));
     case CT_ABST:
       return (message ("aT#%d", c->contents.tid));
+    case CT_NUMABST:
+      return (message ("nT#%d", c->contents.tid));
     case CT_EXPFCN:
       return (message ("<expf: %q >", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
     case CT_PTR:
@@ -639,9 +679,16 @@ ctbase_unparseNotypes (ctbase c)
     case CT_ENUMLIST:
       return (message ("[enumlist]"));
     case CT_CONJ:
-      return (message ("%q/%q", 
-                      ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->a)),
-                      ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->b))));
+      if (ctbase_isAnytype (c))
+       {
+         return (cstring_makeLiteral ("<any>"));
+       }
+      else
+       {
+         return (message ("%q/%q", 
+                          ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->a)),
+                          ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->b))));
+       }
     BADDEFAULT;
     }
   BADEXIT;
@@ -665,6 +712,7 @@ ctbase_unparseDeclaration (ctbase c, /*@only@*/ cstring name) /*@*/
       return (message ("%q %q", cprim_unparse (c->contents.prim), name));
     case CT_USER:
     case CT_ABST:
+    case CT_NUMABST:
       return (message ("%q %q", usymtab_getTypeEntryName (c->contents.tid), name));
     case CT_EXPFCN:
       llcontbuglit ("ctbase_unparseDeclaration: expfcn");
@@ -736,8 +784,12 @@ ctbase_unparseDeclaration (ctbase c, /*@only@*/ cstring name) /*@*/
                           enumNameList_unparseBrief (c->contents.cenum->members),
                           name));
        }
-    case CT_CONJ:      
-      if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
+    case CT_CONJ:
+      if (ctbase_isAnytype (c))
+       {
+         return (message ("<any> %q", name));
+       }
+      else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
        {
          if (!ctype_isSimple (c->contents.conj->a) ||
              !ctype_isSimple (c->contents.conj->b))
@@ -772,7 +824,7 @@ ctbase_unparseDeclaration (ctbase c, /*@only@*/ cstring name) /*@*/
   BADEXIT;
 }
 
-static ctbase ctbase_undump (d_char *c)
+static ctbase ctbase_undump (d_char *c) /*@requires maxRead(*c) >= 2 @*/
 {
   ctbase res;
   char p = **c;
@@ -788,33 +840,37 @@ static ctbase ctbase_undump (d_char *c)
     case 'b':
       return (ctbase_createBool ());
     case 'p':
-      res = ctbase_createPrim (cprim_fromInt (getInt (c)));
-      checkChar (c, '|');
+      res = ctbase_createPrim (cprim_fromInt (reader_getInt (c)));
+      reader_checkChar (c, '|');
       return res;
     case 's':
-      res = ctbase_createUser (typeId_fromInt (getInt (c)));
-      checkChar (c, '|');
+      res = ctbase_createUser (typeId_fromInt (reader_getInt (c)));
+      reader_checkChar (c, '|');
       return res;
     case 'a':
-      res = ctbase_createAbstract (typeId_fromInt (getInt (c)));
-      checkChar (c, '|');
+      res = ctbase_createAbstract (typeId_fromInt (reader_getInt (c)));
+      reader_checkChar (c, '|');
+      return res;
+    case 'n':
+      res = ctbase_createNumAbstract (typeId_fromInt (reader_getInt (c)));
+      reader_checkChar (c, '|');
       return res;
     case 't':
       res = ctbase_makePointer (ctype_undump (c));
-      checkChar (c, '|');
+      reader_checkChar (c, '|');
       return res;
     case 'y':
       res = ctbase_makeArray (ctype_undump (c));
-      checkChar (c, '|');
+      reader_checkChar (c, '|');
       return res;
     case 'F':
       {
        ctype ct = ctype_undump (c);
-       int size;
+       size_t size;
 
-       checkChar (c, '/');
-       size = getInt (c);
-       checkChar (c, '|');
+       reader_checkChar (c, '/');
+       size = size_fromInt (reader_getInt (c));
+       reader_checkChar (c, '|');
        return (ctbase_makeFixedArray (ct, size));
       }
     case 'f':
@@ -911,12 +967,12 @@ static ctbase ctbase_undump (d_char *c)
        bool isExplicit;
        ctype c1, c2;
 
-       isExplicit = bool_fromInt (getInt (c));
-       checkChar (c, '.');
+       isExplicit = bool_fromInt (reader_getInt (c));
+       reader_checkChar (c, '.');
        c1 = ctype_undump (c);
-       checkChar (c, '/');
+       reader_checkChar (c, '/');
        c2 = ctype_undump (c);
-       checkChar (c, '|');
+       reader_checkChar (c, '|');
 
        return (ctbase_makeConj (c1, c2, isExplicit));
       }
@@ -926,7 +982,7 @@ static ctbase ctbase_undump (d_char *c)
       llerror (FLG_SYNTAX, 
               message ("Bad Library line (type): %s", cstring_fromChars (*c)));
 
-      while (**c != '\0')
+  /*drl bee: pbr*/      while (**c != '\0')
        {
          (*c)++;
        }
@@ -968,10 +1024,11 @@ ctbase_dump (ctbase c)
     case CT_PRIM:
       return (message ("p%d|", c->contents.prim));
     case CT_USER:
-      return (message ("s%d|", 
-                      usymtab_convertId (c->contents.tid)));
+      return (message ("s%d|", usymtab_convertTypeId (c->contents.tid)));
     case CT_ABST:
-      return (message ("a%d|", usymtab_convertId (c->contents.tid)));
+      return (message ("a%d|", usymtab_convertTypeId (c->contents.tid)));
+    case CT_NUMABST:
+      return (message ("n%d|", usymtab_convertTypeId (c->contents.tid)));
     case CT_PTR:
       return (message ("t%q|", ctype_dump (c->contents.base)));
     case CT_ARRAY:
@@ -981,6 +1038,7 @@ ctbase_dump (ctbase c)
                       ctype_dump (c->contents.farray->base),
                       (int) c->contents.farray->size));
     case CT_FCN:
+      DPRINTF (("Dump function: %s", ctbase_unparse (c)));
       return (message ("f%q (%q)", ctype_dump (c->contents.fcn->rval),
                       uentryList_dumpParams (c->contents.fcn->params)));
     case CT_STRUCT:
@@ -1041,6 +1099,8 @@ ctbase_copy (/*@notnull@*/ ctbase c)
       return (ctbase_createUser (c->contents.tid));
     case CT_ABST:
       return (ctbase_createAbstract (c->contents.tid));
+    case CT_NUMABST:
+      return (ctbase_createNumAbstract (c->contents.tid));
     case CT_EXPFCN:
       return (ctbase_expectFunction (c->contents.base));
     case CT_PTR:
@@ -1103,9 +1163,8 @@ ctbase_free (/*@only@*/ ctbase c)
          sfree (c);
          break;
        case CT_USER:
-         sfree (c);
-         break;
        case CT_ABST:
+       case CT_NUMABST:
          sfree (c);
          break;
        case CT_PTR:
@@ -1113,17 +1172,8 @@ ctbase_free (/*@only@*/ ctbase c)
          sfree (c);
          break;
        case CT_FCN:
-
-         if (c->contents.fcn->liveparams)
-           {
-             /* Because of liveparams, we know this can be released. */
-
-             /*@-dependenttrans@*/ /*@-unqualifiedtrans@*/
-             uentryList_free (c->contents.fcn->params); 
-             c->contents.fcn->params = NULL;
-             /*@=dependenttrans@*/ /*@=unqualifiedtrans@*/
-           }
-
+         /* Cannot free params: uentryList_free (c->contents.fcn->params);  */ 
+         uentryList_freeShallow (c->contents.fcn->params);
          sfree (c);
          break;
        case CT_STRUCT:
@@ -1157,6 +1207,19 @@ ctbase_expectFunction (ctype c)
   return (f);
 }
 
+static bool
+ctbase_isExpectFunction (/*@notnull@*/ ctbase ct) /*@*/
+{
+  return (ct->type == CT_EXPFCN);
+}
+
+static ctype
+ctbase_getExpectFunction (/*@notnull@*/ ctbase ct)
+{
+  llassert (ctbase_isExpectFunction (ct));
+  return ct->contents.base;
+}
+
 static bool
 ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep)
 {
@@ -1248,13 +1311,12 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep
          return (context_msgBoolInt ());
        }
 
-      if ((c1tid == CT_BOOL && (c2tid == CT_ABST || c2tid == CT_USER))) {
+      if ((c1tid == CT_BOOL && (ctuid_isAnyUserType (c2tid)))) {
        ctype t2c = c2->contents.base;
-
        return (ctype_isBool (t2c));
       }
 
-      if ((c2tid == CT_BOOL && (c1tid == CT_ABST || c1tid == CT_USER))) {
+      if ((c2tid == CT_BOOL && (ctuid_isAnyUserType (c1tid)))) {
        ctype t1c = c1->contents.base;
 
        return (ctype_isBool (t1c));
@@ -1319,7 +1381,7 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep
   
       if (context_getFlag (FLG_FORWARDDECL))
        {
-         if (c1tid == CT_ABST || c1tid == CT_USER)
+         if (ctuid_isAnyUserType (c1tid))
            {
              if (ctuid_isAP (c2tid))
                {
@@ -1338,7 +1400,7 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep
                }
            }
          
-         if (c2tid == CT_ABST || c2tid == CT_USER)
+         if (ctuid_isAnyUserType (c2tid))
            {
              if (ctuid_isAP (c1tid))
                {
@@ -1375,7 +1437,7 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep
     case CT_BOOL:
       return (TRUE);
     case CT_ABST:
-      return (typeId_equal (c1->contents.tid, c2->contents.tid));
+    case CT_NUMABST:
     case CT_USER:
       return (typeId_equal (c1->contents.tid, c2->contents.tid));
     case CT_ENUM:      
@@ -1435,19 +1497,36 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep
                c1->contents.su->name,
                c2->contents.su->name));
 
-      if (!cstring_isEmpty (c1->contents.su->name))
+      if (isFakeTag (c1->contents.su->name)
+         && isFakeTag (c2->contents.su->name))
        {
-         return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
+         /* Both fake tags, check structure */
+         if (cstring_equal (c1->contents.su->name, c2->contents.su->name))
+           {
+             return TRUE;
+           }
+         else
+           {
+             return uentryList_matchFields (c1->contents.su->fields, 
+                                            c2->contents.su->fields);
+           }
        }
       else
        {
-         if (!cstring_isEmpty (c2->contents.su->name))
+         if (!cstring_isEmpty (c1->contents.su->name))
            {
-             return FALSE;
+             return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
+           }
+         else
+           {
+             if (!cstring_isEmpty (c2->contents.su->name))
+               {
+                 return FALSE;
+               }
+             
+             llcontbuglit ("ctbase_genMatch: match fields");
+             return (FALSE);
            }
-
-         llcontbuglit ("ctbase_genMatch: match fields");
-         return (FALSE);
        }
     default:
       llcontbug (message ("ctbase_genMatch: unknown type: %d\n", (int)c1tid));
@@ -1586,6 +1665,20 @@ ctbase_createAbstract (typeId u)
   return (c);
 }
 
+static /*@only@*/ ctbase
+ctbase_createNumAbstract (typeId u)
+{
+  ctbase c = ctbase_new ();
+
+  c->type = CT_NUMABST;
+  c->contents.tid = u;
+  
+  /* also check its abstract? */
+  
+  llassert (typeId_isValid (c->contents.tid));
+  return (c);
+}
+
 static /*@only@*/ ctbase
 ctbase_createUnknown (void)
 {
@@ -1629,7 +1722,7 @@ ctbase_makeArray (ctype b)
 }
 
 static /*@notnull@*/ /*@only@*/ ctbase
-ctbase_makeFixedArray (ctype b, long size)
+ctbase_makeFixedArray (ctype b, size_t size)
 {
   ctbase c = ctbase_new ();
 
@@ -1671,14 +1764,12 @@ ctbase_makeFunction (ctype b, /*@only@*/ uentryList p)
       rval = ctype_makeFunction (ctb->contents.fcn->rval, p);
 
       c->contents.fcn->rval = rval;
-      c->contents.fcn->params = ctb->contents.fcn->params;
-      c->contents.fcn->liveparams = FALSE;
+      c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params); /* no copy before */
     }
   else
     {
       c->contents.fcn->rval = b;
-      /*@i@*/ c->contents.fcn->params = p;
-      c->contents.fcn->liveparams = TRUE;
+      c->contents.fcn->params = uentryList_copy (p); /* no copy before */
       /*@-branchstate@*/ /* p is really released on this branch */
     } 
   /*@=branchstate@*/
@@ -1716,15 +1807,12 @@ ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p)
       rval = ctype_makeNFParamsFunction (ctb->contents.fcn->rval, p);
       
       c->contents.fcn->rval = rval;
-      c->contents.fcn->params = ctb->contents.fcn->params;
-      c->contents.fcn->liveparams = FALSE;
+      c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params);
     }
   else
     {
       c->contents.fcn->rval = b;
-      /*@i@*/ c->contents.fcn->params = p;
-      c->contents.fcn->liveparams = TRUE;
-
+      c->contents.fcn->params = uentryList_copy (p);
       /*@-branchstate@*/ 
     }
   /*@=branchstate@*/
@@ -1734,7 +1822,7 @@ ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p)
 }
 
 static /*@only@*/ ctbase
-  ctbase_makeLiveFunction (ctype b, /*@owned@*/ uentryList p)
+  ctbase_makeLiveFunction (ctype b, /*@only@*/ uentryList p)
 {
   ctbase c = ctbase_new ();
 
@@ -1743,26 +1831,10 @@ static /*@only@*/ ctbase
   c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
   c->contents.fcn->rval = b;
   c->contents.fcn->params = p;
-  c->contents.fcn->liveparams = TRUE;
 
   /*@-mustfree@*/ return (c); /*@=mustfree@*/
 }
 
-static /*@only@*/ ctbase
-  ctbase_makeRealFunction (ctype b, /*@dependent@*/ uentryList p)
-{
-  ctbase c = ctbase_new ();
-
-  c->type = CT_FCN;
-  
-  c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
-  c->contents.fcn->rval = b;
-  c->contents.fcn->params = p;
-  c->contents.fcn->liveparams = FALSE;
-
-  return (c);
-}
-
 static /*@observer@*/ /*@notnull@*/ ctbase
 ctbase_realFunction (/*@dependent@*/ /*@notnull@*/ ctbase c)
 {
@@ -1821,6 +1893,23 @@ static /*@only@*/ ctbase
   return (c);
 }
 
+static bool ctbase_isAnytype (/*@notnull@*/ ctbase b)
+{
+  /*
+  ** A unknown|dne conj is a special representation for an anytype.
+  */
+
+  if (b->type == CT_CONJ)
+    {
+      /*@access ctype@*/
+      return (b->contents.conj->a == ctype_unknown
+             && b->contents.conj->b == ctype_dne);
+      /*@noaccess ctype@*/ 
+    }
+  
+  return FALSE;
+}
+
 static ctype
 ctbase_getConjA (/*@notnull@*/ ctbase c)
 {
@@ -1939,7 +2028,7 @@ ctbase_baseisExpFcn (ctype c)
 
   if (cb->type == CT_FCN)
     {
-      c = ctype_removePointers (ctype_returnValue (c));
+      c = ctype_removePointers (ctype_getReturnType (c));
 
       cb = ctype_getCtbase (c);
       llassert (ctbase_isDefined (cb));
@@ -1962,13 +2051,13 @@ ctbase_newBase (ctype c, ctype p)
 
   DPRINTF (("New base: %s / %s", ctype_unparse (c), ctype_unparse (p)));
 
-  cb = ctype_getCtbase (c);
-
-  if (ctype_isUndefined (c))
+  if (ctype_isUndefined (c) || ctype_isUnknown (c))
     {
       return p;
     }
 
+  cb = ctype_getCtbase (c);
+
   if (ctype_isConj (p))
     {
       ctbase pb = ctype_getCtbase (p);
@@ -2003,6 +2092,7 @@ ctbase_newBase (ctype c, ctype p)
     case CT_USER:
     case CT_ENUM:
     case CT_ABST:
+    case CT_NUMABST:
     case CT_STRUCT:
     case CT_UNION:
     case CT_EXPFCN:
@@ -2024,7 +2114,7 @@ ctbase_newBase (ctype c, ctype p)
     case CT_ARRAY:
       return (ctype_makeArray (ctbase_newBase (cb->contents.base, p)));
     case CT_FCN:
-      return (ctype_makeRealFunction (ctbase_newBase (cb->contents.fcn->rval, p),
+      return (ctype_makeRawFunction (ctbase_newBase (cb->contents.fcn->rval, p),
                                      cb->contents.fcn->params));
     case CT_CONJ:
       return (ctype_makeConjAux (ctbase_newBase (cb->contents.conj->a, p),
@@ -2061,7 +2151,7 @@ ctbase_newBaseExpFcn (ctype c, ctype p)
   if (!ctbase_isFunction (cb))
     llbuglit ("ctbase_newBaseExpFcn: expFcn -> not a function");
   
-  tmpct = ctype_getBaseType (ctype_returnValue (c));
+  tmpct = ctype_getBaseType (ctype_getReturnType (c));
   
   /*
   ** pointers before expfcn -> p are pointers to function, not result
@@ -2131,7 +2221,7 @@ ctbase_newBaseExpFcn (ctype c, ctype p)
     }
 
  exitLoop:
-  tmpct = ctype_returnValue (c);
+  tmpct = ctype_getReturnType (c);
 
   /*
   ** pointers to expf are pointers to return value
@@ -2182,7 +2272,7 @@ ctbase_newBaseExpFcn (ctype c, ctype p)
   ** pointers to fp are pointers to function type
   */
 
-  ret = ctype_makeRealFunction (p, ctargs);
+  ret = ctype_makeRawFunction (p, uentryList_copy (ctargs));
   
   while (ctype_getCtKind (fp) > CTK_PLAIN)
     {
@@ -2240,6 +2330,7 @@ ctbase_getBaseType (/*@notnull@*/ ctbase c)
     case CT_ENUMLIST:
     case CT_BOOL:
     case CT_ABST:
+    case CT_NUMABST:
     case CT_FCN:
     case CT_STRUCT:
     case CT_UNION:
@@ -2291,12 +2382,13 @@ ctbase_compare (ctbase c1, ctbase c2, bool strict)
     case CT_BOOL:
       return 0;
     case CT_USER:
-      return (int_compare (c1->contents.tid, c2->contents.tid));
+      return (typeId_compare (c1->contents.tid, c2->contents.tid));
     case CT_ENUMLIST:       
       return 1;
     case CT_ENUM:              /* for now, keep like abstract */
     case CT_ABST:
-      return (int_compare (c1->contents.tid, c2->contents.tid));
+    case CT_NUMABST:
+      return (typeId_compare (c1->contents.tid, c2->contents.tid));
     case CT_PTR:
       return (ctype_compare (c1->contents.base, c2->contents.base));
     case CT_FIXEDARRAY:
@@ -2340,6 +2432,10 @@ ctbase_compare (ctbase c1, ctbase c2, bool strict)
        }
       }
 
+      DPRINTF (("Comparing fields: %s / %s",
+               ctbase_unparse (c1),
+               ctbase_unparse (c2)));
+
       return (uentryList_compareFields (c1->contents.su->fields,
                                        c2->contents.su->fields));
     case CT_CONJ:
@@ -2404,12 +2500,18 @@ ctbase_isKind2 (/*@notnull@*/ ctbase c, ctuid kind1, ctuid kind2)
 static bool
 ctbase_isAbstract (/*@notnull@*/ ctbase c)
 {
-  return (c->type == CT_ABST);
+  return (c->type == CT_ABST || c->type == CT_NUMABST);
+}
+
+static bool
+ctbase_isNumAbstract (/*@notnull@*/ ctbase c)
+{
+  return (c->type == CT_NUMABST);
 }
 
 static bool ctbase_isUA (ctbase c) 
 {
-  return (ctbase_isDefined (c) && ((c)->type == CT_USER || (c)->type == CT_ABST));
+  return (ctbase_isDefined (c) && (ctuid_isAnyUserType (c->type)));
 }
 
 static bool
@@ -2449,7 +2551,7 @@ ctbase_almostEqual (ctbase c1, ctbase c2)
     case CT_BOOL:
       return TRUE;
     case CT_ABST:
-      return (typeId_equal (c1->contents.tid, c2->contents.tid));
+    case CT_NUMABST:
     case CT_USER:
       return (typeId_equal (c1->contents.tid, c2->contents.tid));
     case CT_ENUM:      
@@ -2486,3 +2588,93 @@ ctbase_almostEqual (ctbase c1, ctbase c2)
       return (FALSE);
     }
 }
+
+/*drl added July 02, 001
+  called by ctype_getArraySize
+*/
+
+size_t ctbase_getArraySize (ctbase ctb)
+{
+  /*drl 1/25/2002 fixed discovered by Jim Francis */
+  ctbase r;
+  
+  llassert (ctbase_isDefined (ctb) );
+  r = ctbase_realType (ctb);
+  llassert (ctbase_isFixedArray(r) );
+
+  return (r->contents.farray->size);
+}
+
+bool ctbase_isBigger (ctbase ct1, ctbase ct2)
+{
+  if (ct1 != NULL && ct2 != NULL
+      && (ct1->type == CT_PRIM && ct2->type == CT_PRIM))
+    {
+      /* Only compare sizes for primitives */
+      cprim cp1 = ct1->contents.prim;
+      cprim cp2 = ct2->contents.prim;
+      int nbits1 = cprim_getExpectedBits (cp1);
+      int nbits2 = cprim_getExpectedBits (cp2);
+
+      if (nbits1 > nbits2) {
+       return TRUE;
+      } else {
+       return FALSE;
+      }
+    }
+  else
+    {
+      return FALSE;
+    }
+}
+
+int ctbase_getSize (ctbase ct)
+{
+  if (ct == NULL) 
+    {
+      return 0;
+    }
+  
+  switch (ct->type) 
+    {
+    case CT_UNKNOWN:
+    case CT_BOOL:
+    case CT_PRIM:
+      {
+       cprim cp = ct->contents.prim;
+       int nbits = cprim_getExpectedBits (cp);
+       return nbits;
+      }
+    case CT_USER:
+    case CT_ABST:
+    case CT_NUMABST:
+    case CT_EXPFCN:
+      {
+       return 0;
+      }
+    case CT_PTR:
+      {
+       /* Malloc returns void *, but they are bytes.  Normal void * is pointer size. */
+       if (ctype_isVoid (ct->contents.base)) 
+         {
+           return 8;
+         }
+       else
+         {
+           return ctype_getSize (ct->contents.base);
+         }
+      }
+    case CT_FIXEDARRAY: 
+    case CT_ARRAY:
+    case CT_FCN:
+    case CT_STRUCT:
+    case CT_UNION:
+    case CT_ENUM:
+    case CT_CONJ:
+      break;
+      BADDEFAULT;
+    }
+
+  return 0;
+      
+}
This page took 0.085139 seconds and 4 git commands to generate.