]> andersk Git - splint.git/blobdiff - src/clabstract.c
Fixed problem with loop guards in loop test effects. New test case
[splint.git] / src / clabstract.c
index db822877e72bf33e107f712fa9bded90270f267b..10dbd041058d2c21b04b03bddd51202c350a8186 100644 (file)
@@ -1,6 +1,6 @@
 /*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2001 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2002 University of Virginia,
 **         Massachusetts Institute of Technology
 **
 ** This program is free software; you can redistribute it and/or modify it
@@ -17,9 +17,9 @@
 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 ** MA 02111-1307, USA.
 **
-** For information on lclint: lclint-request@cs.virginia.edu
-** To report a bug: lclint-bug@cs.virginia.edu
-** For more information: http://lclint.cs.virginia.edu
+** For information on splint: info@splint.org
+** To report a bug: splint-bug@splint.org
+** For more information: http://www.splint.org
 */
 /*
 ** clabstract.c
@@ -28,7 +28,7 @@
 **
 */
 
-# include "lclintMacros.nf"
+# include "splintMacros.nf"
 # include "llbasic.h"
 # include "cgrammar.h"
 
 */
 
 /*drl*/
-/*@only@*/ static  constraintList fcnConstraints = NULL;
-
-/*end drl*/
-
-/*drl */
-static /*@only@*/   constraintList implicitFcnConstraints = NULL;
-
-
-//static  constraintList fcnPreConditions = NULL;
+static /*@only@*/ constraintList implicitFcnConstraints = NULL;
 
 static void clabstract_prepareFunction (uentry p_e) /*@modifies p_e@*/ ;
 static bool fcnNoGlobals = FALSE;
@@ -501,7 +493,7 @@ declareEnumList (enumNameList el, ctype c, fileloc loc)
 
 static /*@dependent@*/ uentryList currentParamList;
 
-/*drl added 3-28-2001*/
+/*drl added 3-28-2002*/
 /* this function takes a list of paramentar and generates a list
    of constraints.
    Currently the only constraints gnerated are MaxSet(p) >= 0 for all pointers
@@ -536,7 +528,7 @@ void  setImplictfcnConstraints (void)
        chagned this is MaxSet(s) == 0 to MaxSet(s) >= 0 */
       
       c = constraint_makeSRefWriteSafeInt (s, 0);
-       // constraint_makeSRefSetBufferSize (s, 0);
+      /* constraint_makeSRefSetBufferSize (s, 0); */
       implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c);
     }
   end_uentryList_elements;
@@ -636,6 +628,7 @@ static /*@exposed@*/ uentry clabstract_globalDeclareFunction (idDecl tid)
   ue = usymtab_supGlobalEntryReturn (ue);
   DPRINTF (("After supercede function: %s", uentry_unparseFull (ue)));
 
+  DPRINTF (("Enter function: %s", uentry_unparseFull (ue)));
   context_enterFunction (ue);
   enterFunctionParams (uentry_getParams (ue));
 
@@ -669,6 +662,9 @@ static /*@only@*/ uentry globalDeclareOldStyleFunction (idDecl tid)
   uentry_setDefined (ue, g_currentloc);
   uentry_checkParams (ue);
   resetStorageClass ();
+
+  /* context_enterOldStyleScope (); */
+
   return (ue);
 }
 
@@ -679,6 +675,13 @@ static void oldStyleDeclareFunction (/*@only@*/ uentry e)
 
   llassert (ctype_isFunction (rt));
 
+  if (uentry_hasStateClauseList (e) 
+      || uentry_hasConditions (e))
+    {
+      llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
+                            fileloc_unparse (g_currentloc), uentry_unparse (e)));
+    }
+
   e = usymtab_supGlobalEntryReturn (e);
 
   context_enterFunction (e);
@@ -687,6 +690,28 @@ static void oldStyleDeclareFunction (/*@only@*/ uentry e)
   resetStorageClass ();
 }
 
+static void oldStyleCompleteFunction (/*@only@*/ uentry e)
+{
+  uentryList params = saveParamList;
+  ctype rt = uentry_getType (e);
+
+  llassert (ctype_isFunction (rt));
+
+  if (uentry_hasStateClauseList (e) 
+      || uentry_hasConditions (e))
+    {
+      llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
+                            fileloc_unparse (g_currentloc), uentry_unparse (e)));
+    }
+
+  e = usymtab_supGlobalEntryReturn (e);
+
+  context_completeOldStyleFunction (e);
+  enterFunctionParams (params);
+  saveParamList = uentryList_undefined;
+  resetStorageClass ();
+}
+
 void clabstract_declareFunction (idDecl tid) /*@globals undef saveFunction; @*/
 {
   uentry ue;
@@ -697,6 +722,7 @@ void clabstract_declareFunction (idDecl tid) /*@globals undef saveFunction; @*/
     {
       ue = globalDeclareOldStyleFunction (tid);
       saveFunction = ue;
+      DPRINTF (("Set save function: %s", uentry_unparseFull (ue)));
     }
   else
     {
@@ -886,7 +912,7 @@ checkTypeDecl (uentry e, ctype rep)
       uentry le  = usymtab_getTypeEntry (llm);
 
       uentry_setDeclared (e, g_currentloc); 
-      uentry_setSref (e, sRef_makeGlobal (llm, uentry_getType (le)));
+      uentry_setSref (e, sRef_makeGlobal (llm, uentry_getType (le), stateInfo_currentLoc ()));
 
       DPRINTF (("Here we are: %s / %s",
                n, context_getBoolName ()));
@@ -1051,7 +1077,7 @@ fixUentryList (idDeclList tl, qtype q)
 ** Microsoft VC++.  It is not supported by the ANSI standard.  
 **
 ** The inner fields are added to the outer structure.  This is meaningful
-** for nesting structs inside unions, but lclint does no related 
+** for nesting structs inside unions, but Splint does no related 
 ** checking.
 */
 
@@ -1066,6 +1092,11 @@ fixUnnamedDecl (qtype q)
 
       return (uentryList_copy (res));
     }
+  else if (ctype_isEnum (ct))
+    {
+      /* evans 2002-02-05: nothing to do for unnamed enum lists */
+      return uentryList_undefined;
+    }
   else
     {      
       BADBRANCHCONT;
@@ -1142,7 +1173,7 @@ setGenericParamList (/*@dependent@*/ uentryList pm)
 }
 
 void
-setProcessingTypedef (/*@only@*/ qtype q)
+setProcessingTypedef (qtype q)
 {
   ProcessingTypedef = TRUE;
 
@@ -1158,7 +1189,7 @@ unsetProcessingVars ()
 }
 
 void 
-doneParams ()
+oldStyleDoneParams ()
 {  
   if (ProcessingParams)
     {
@@ -1175,7 +1206,7 @@ doneParams ()
          uentry_setType (saveFunction, ct2);
          ProcessingParams = FALSE;
 
-         oldStyleDeclareFunction (saveFunction);
+         oldStyleCompleteFunction (saveFunction);
          saveFunction = uentry_undefined;
          resetGlobals ();
        }
@@ -1203,6 +1234,8 @@ checkDoneParams ()
       ctype ct = ctype_getReturnType (uentry_getType (saveFunction));
       ctype ct2;
 
+      DPRINTF (("save function: %s", uentry_unparseFull (saveFunction)));
+
       uentryList_elements (saveParamList, current)
        {
          uentry_setType (current, ctype_int); /* all params are ints */
@@ -1218,6 +1251,47 @@ checkDoneParams ()
     }
 }
 
+void clabstract_declareType (/*@only@*/ exprNodeList decls, /*@only@*/ warnClause warn)
+{
+  llassert (ProcessingTypedef);
+
+  DPRINTF (("Declare type: %s", exprNodeList_unparse (decls)));
+
+  if (warnClause_isDefined (warn))
+    {
+      DPRINTF (("Has a warn clause!"));
+      DPRINTF (("Warn: %s", warnClause_unparse (warn)));
+
+      exprNodeList_elements (decls, el)
+       {
+         uentry ue = exprNode_getUentry (el);
+         cstring uname = uentry_getName (ue);
+
+         DPRINTF (("Entry: %s", exprNode_unparse (el)));
+
+         /*
+         ** Need to lookup again to make sure we have the right one...
+         */
+
+         ue = usymtab_lookupExposeGlob (uname);
+
+         llassert (uentry_isValid (ue));
+         llassert (uentry_isDatatype (ue));
+
+         DPRINTF (("Warning for %s: %s",
+                   uentry_unparse (ue), warnClause_unparse (warn)));
+
+         uentry_addWarning (ue, warnClause_copy (warn));
+         DPRINTF (("After add warning: %s", uentry_unparseFull (ue)));
+         cstring_free (uname);
+       } end_exprNodeList_elements;
+    }
+
+  warnClause_free (warn);
+  exprNodeList_free (decls);
+  unsetProcessingTypedef ();
+}
+
 void
 unsetProcessingTypedef ()
 {
@@ -1227,13 +1301,14 @@ unsetProcessingTypedef ()
 void checkConstant (qtype t, idDecl id) 
 {
   uentry e;
-
+  
   id = idDecl_fixBase (id, t);
   e = uentry_makeIdConstant (id);
-
+  
   reflectStorageClass (e);
   resetStorageClass ();
 
+  DPRINTF (("Constant: %s", uentry_unparseFull (e)));
   usymtab_supGlobalEntry (e);
 }
 
@@ -1266,9 +1341,14 @@ void checkValueConstant (qtype t, idDecl id, exprNode e)
            {
              uentry_mergeConstantValue (ue, multiVal_copy (exprNode_getValue (e)));
            }
+         else
+           {
+             DPRINTF (("No value: %s", exprNode_unparse (e)));
+           }
        }
     }
 
+  DPRINTF (("Constant value: %s", uentry_unparseFull (ue)));
   usymtab_supGlobalEntry (ue);
 }
 
@@ -1284,7 +1364,7 @@ void processNamedDecl (idDecl t)
   t = idDecl_fixBase (t, processingType);
 
   DPRINTF (("Declare: %s", idDecl_unparse (t)));
-
+  
   if (ProcessingGlobals)
     {
       cstring id = idDecl_getName (t);
@@ -1330,9 +1410,11 @@ void processNamedDecl (idDecl t)
            {
              uentry cparam = uentryList_getN (saveParamList, paramno);
 
+             DPRINTF (("Processing param: %s", uentry_unparseFull (cparam)));
              uentry_setType (cparam, idDecl_getCtype (t));
              uentry_reflectQualifiers (cparam, idDecl_getQuals (t));
              uentry_setDeclaredOnly (cparam, context_getSaveLocation ());
+             DPRINTF (("Processing param: %s", uentry_unparseFull (cparam)));
            }
          else
            {
@@ -1720,10 +1802,12 @@ void setNewStyle ()              { flipNewStyle = TRUE; }
                cstring_makeLiteral ("Old style function declaration"),
                g_currentloc); 
 
+  DPRINTF (("Handle old style params: %s", uentryList_unparseFull (params)));
+
   uentryList_elements (params, current)
     {
       uentry_setParam (current);
-      uentry_setSref (current, sRef_makeParam (paramno, ctype_unknown));
+      uentry_setSref (current, sRef_makeParam (paramno, ctype_unknown, stateInfo_makeLoc (uentry_whereLast (current))));
       paramno++;
     } end_uentryList_elements;
 
@@ -1764,7 +1848,8 @@ doVaDcl ()
       
       if (i >= 0)
        {
-         e = uentry_makeVariableSrefParam (id, c, sRef_makeParam (i, c));
+         fileloc loc = context_getSaveLocation ();
+         e = uentry_makeVariableSrefParam (id, c, loc, sRef_makeParam (i, c, stateInfo_makeLoc (loc)));
        }
       else
        {
@@ -1944,15 +2029,15 @@ doVaDcl ()
                }
              else 
                {
-                 if (ctype_isAbstract (ct))
+                 if (ctype_isAbstract (rt))
                    {
                      voptgenerror 
                        (FLG_ABSTRACT,
                         message
-                        ("Modifies clause in header file arrow accesses abstract "
+                        ("Modifies clause arrow accesses inaccessible abstract "
                          "type %s (interface modifies clause should not depend "
                          "on or expose type representation): %q",
-                         ctype_unparse (ct),
+                         ctype_unparse (rt),
                          sRef_unparse (s)),
                         g_currentloc);
                    }
@@ -1995,11 +2080,11 @@ sRef checkStateClausesId (uentry ue)
     {
       voptgenerror 
        (FLG_COMMENTERROR,
-        message ("Global variable %s used special clause.  (Global variables "
-                 "are not recognized in special clauses.  If there is "
+        message ("Global variable %s used state clause.  (Global variables "
+                 "are not recognized in state clauses.  If there is "
                  "sufficient interest in support for this, it may be "
                  "added to a future release.  Send mail to "
-                 "lclint@cs.virginia.edu.)",
+                 "info@splint.org.)",
                  s),
         g_currentloc);
       
@@ -2038,11 +2123,12 @@ sRef checkStateClausesId (uentry ue)
 sRef checkbufferConstraintClausesId (uentry ue)
 {
   cstring s = uentry_rawName (ue);
+
   if (cstring_equalLit (s, "result"))
     {
       if (optgenerror 
          (FLG_SYNTAX, 
-          message ("Special clause list uses %s which is a variable and has special "
+          message ("Function clause list uses %s which is a variable and has special "
                    "meaning in a modifies list.  (Special meaning assumed.)", s), 
           g_currentloc))
        {
@@ -2050,7 +2136,8 @@ sRef checkbufferConstraintClausesId (uentry ue)
        }
     }
   
-  return sRef_saveCopy( uentry_getSref (ue) );
+  DPRINTF (("constrant id: %s", uentry_unparseFull (ue)));
+  return sRef_saveCopy (uentry_getSref (ue)); /*@i523 why the saveCopy? */
 }
 
 void checkModifiesId (uentry ue)
@@ -2118,7 +2205,7 @@ void checkModifiesId (uentry ue)
        }
       else
        {
-         fileloc loc = fileloc_decColumn (g_currentloc, cstring_length (s));
+         fileloc loc = fileloc_decColumn (g_currentloc, size_toInt (cstring_length (s)));
          ret = sRef_undefined;
 
          voptgenerror 
@@ -2143,7 +2230,7 @@ sRef fixStateClausesId (cstring s)
 
   if (cstring_equalLit (s, "result"))
     {
-      ret = sRef_makeResult ();
+      ret = sRef_makeResult (ctype_unknown);
     }
   else
     {
@@ -2175,7 +2262,7 @@ sRef fixStateClausesId (cstring s)
                          "are not recognized in function clauses.  If there is "
                          "sufficient interest in support for this, it may be "
                          "added to a future release.  Send mail to "
-                         "lclint@cs.virginia.edu.)",
+                         "info@splint.org.)",
                          s), 
                 g_currentloc);
              
@@ -2184,9 +2271,41 @@ sRef fixStateClausesId (cstring s)
        }
       else
        {
-         fileloc loc = fileloc_decColumn (g_currentloc, cstring_length (s));
+         /*@i222@*/
+         /*drl handle structure invariant */
+
+         /*@i222@*/
+         /*check that we're in a structure */
+# if 0\r
+                 /*@unused@*/    uentryList ueL;
+         /*@unused@*/ uentry ue2;
+         /*@unused@*/ ctype ct;\r
+# endif
+         fileloc loc = fileloc_decColumn (g_currentloc, size_toInt (cstring_length (s)));
          ret = sRef_undefined; 
-         
+# if 0
+         /*drl commenting this out for now 
+         ct = context_getLastStruct ( ct );
+
+         llassert( ctype_isStruct(ct) );
+
+         ueL =  ctype_getFields (ct);
+
+         ue2 = uentryList_lookupField (ueL, s);
+
+         if (!uentry_isUndefined(ue2) )
+           {
+             ret = uentry_getSref(ue2);
+             
+             DPRINTF((
+                      message("Got field in structure in the annotation constraint: %s (or sref: %s)", s, sRef_unparse(ret) )
+                      ));
+             
+             return ret;
+           }
+         */\r
+# endif\r
+
          voptgenerror 
            (FLG_UNRECOG, 
             message ("Unrecognized identifier in function clause: %s", s), 
@@ -2250,11 +2369,3 @@ sRef clabstract_checkGlobal (exprNode e)
   exprNode_free (e);
   return sRef_copy (s);
 }
-
-
-
-
-
-
-
-
This page took 0.055961 seconds and 4 git commands to generate.