]> andersk Git - splint.git/blobdiff - src/context.c
Added manual test cases.
[splint.git] / src / context.c
index a4963c21c2885d3cfeb659d0dd8f60ea0502d5ce..e3706c8632fa65330edfddb1c05b33ae9e46be5b 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
@@ -19,7 +19,7 @@
 **
 ** 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 more information: http://www.splint.org
 */
 /*
 ** context.c
@@ -63,7 +63,8 @@ typedef enum {
   CX_GLOBAL, CX_INNER, 
   CX_FUNCTION, CX_FCNDECLARATION,
   CX_MACROFCN, CX_MACROCONST, CX_UNKNOWNMACRO, 
-  CX_ITERDEF, CX_ITEREND,
+  CX_ITERDEF, CX_ITEREND, 
+  CX_OLDSTYLESCOPE, /* Parsing old-style parameter declarations */
   CX_LCL, CX_LCLLIB, CX_MT
 } kcontext;
 
@@ -134,7 +135,6 @@ static struct
   /*@reldef@*/ maccesst *moduleaccess; /* Not defined is nmods == 0. */
   
   kcontext kind;
-  kcontext savekind;
 
   ctype boolType;
 
@@ -151,12 +151,15 @@ static struct
 
   metaStateTable stateTable; /* User-defined state information. */
   annotationTable annotTable; /* User-defined annotations table. */
-  union 
+  union u_cont
     {
       bool glob;
       int  cdepth;
       /*@dependent@*/ /*@exposed@*/ uentry  fcn;
     } cont;
+
+  kcontext savekind;
+  union u_cont savecont;
 } gc;
 
 static /*@exposed@*/ cstring context_exposeString (flagcode p_flag) ;
@@ -721,21 +724,21 @@ context_resetAllFlags (void)
            case FLG_INDENTSPACES: 
              val = DEFAULT_INDENTSPACES; break;
            case FLG_EXTERNALNAMELEN:
-             val = DEFAULT_EXTERNALNAMELEN; break;
+             val = ISO99_EXTERNALNAMELEN; break;
            case FLG_INTERNALNAMELEN:
-             val = DEFAULT_INTERNALNAMELEN; break;
+             val = ISO99_INTERNALNAMELEN; break;
            case FLG_COMMENTCHAR: 
              val = (int) DEFAULT_COMMENTCHAR; break;
            case FLG_CONTROLNESTDEPTH:
-             val = (int) DEFAULT_CONTROLNESTDEPTH; break;
+             val = (int) ISO99_CONTROLNESTDEPTH; break;
            case FLG_STRINGLITERALLEN:
-             val = (int) DEFAULT_STRINGLITERALLEN; break;
+             val = (int) ISO99_STRINGLITERALLEN; break;
            case FLG_INCLUDENEST:
-             val = (int) DEFAULT_INCLUDENEST; break;
+             val = (int) ISO99_INCLUDENEST; break;
            case FLG_NUMSTRUCTFIELDS:
-             val = (int) DEFAULT_NUMSTRUCTFIELDS; break;
+             val = (int) ISO99_NUMSTRUCTFIELDS; break;
            case FLG_NUMENUMMEMBERS:
-             val = (int) DEFAULT_NUMENUMMEMBERS; break;
+             val = (int) ISO99_NUMENUMMEMBERS; break;
            case FLG_EXPECT:
            case FLG_LCLEXPECT:
              break;
@@ -817,10 +820,16 @@ context_resetAllFlags (void)
 
   /*@i34 move this into flags.def */
     
+  gc.flags[FLG_OBVIOUSLOOPEXEC] = TRUE;
   gc.flags[FLG_MODIFIES] = TRUE;
   gc.flags[FLG_NESTCOMMENT] = TRUE;
   gc.flags[FLG_GLOBALS] = TRUE;
   gc.flags[FLG_FULLINITBLOCK] = TRUE;
+  gc.flags[FLG_INITSIZE] = TRUE;
+  gc.flags[FLG_INITALLELEMENTS] = TRUE;
+
+  gc.flags[FLG_STRINGLITTOOLONG] = TRUE;
+
   gc.flags[FLG_LIKELYBOOL] = TRUE;
   gc.flags[FLG_ZEROPTR] = TRUE;
   gc.flags[FLG_NUMLITERAL] = TRUE;
@@ -841,6 +850,7 @@ context_resetAllFlags (void)
   gc.flags[FLG_SIZEOFFORMALARRAY] = TRUE;
   gc.flags[FLG_FIXEDFORMALARRAY] = TRUE;
 
+  gc.flags[FLG_UNRECOGDIRECTIVE] = TRUE;
   gc.flags[FLG_WARNUSE] = TRUE;
   gc.flags[FLG_PREDASSIGN] = TRUE;
   gc.flags[FLG_MODOBSERVER] = TRUE;
@@ -857,6 +867,7 @@ context_resetAllFlags (void)
   gc.flags[FLG_FORMATTYPE] = TRUE;
   gc.flags[FLG_BADFLAG] = TRUE;
   gc.flags[FLG_WARNFLAGS] = TRUE;
+  gc.flags[FLG_WARNRC] = TRUE;
   gc.flags[FLG_FILEEXTENSIONS] = TRUE;
   gc.flags[FLG_WARNUNIXLIB] = TRUE;
   gc.flags[FLG_WARNPOSIX] = TRUE;
@@ -969,17 +980,19 @@ context_setMode (cstring s)
       flagcode modeflags[] = 
        {
          FLG_ENUMINT, FLG_MACROMATCHNAME,
+         FLG_STRINGLITNOROOM,
          FLG_MACROUNDEF, FLG_RELAXQUALS, 
          FLG_USEALLGLOBS, FLG_CHECKSTRICTGLOBALS,
          FLG_CHECKSTRICTGLOBALIAS,
          FLG_CHECKEDGLOBALIAS,
          FLG_CHECKMODGLOBALIAS,
          FLG_PREDBOOLOTHERS, FLG_PREDBOOLINT,
+         FLG_UNSIGNEDCOMPARE,
          FLG_PARAMUNUSED, FLG_VARUNUSED, FLG_FUNCUNUSED, 
          FLG_TYPEUNUSED,
          FLG_CONSTUNUSED, FLG_ENUMMEMUNUSED, FLG_FIELDUNUSED,
-         FLG_PTRNUMCOMPARE, FLG_BOOLCOMPARE, FLG_MUTREP, 
-         FLG_NOEFFECT, FLG_IMPTYPE,
+         FLG_PTRNUMCOMPARE, FLG_BOOLCOMPARE, FLG_UNSIGNEDCOMPARE,
+         FLG_MUTREP, FLG_NOEFFECT, FLG_IMPTYPE,
          FLG_RETVALOTHER, FLG_RETVALBOOL, FLG_RETVALINT,
          FLG_SPECUNDEF, FLG_INCONDEFS, FLG_INCONDEFSLIB, FLG_MISPLACEDSHAREQUAL,
          FLG_MATCHFIELDS,
@@ -1022,7 +1035,9 @@ context_setMode (cstring s)
          FLG_EXPORTLOCAL,
 
          FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
-         FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE, 
+         FLG_MUSTFREEONLY, 
+         FLG_MUSTFREEFRESH,
+         FLG_MUSTDEFINE, FLG_GLOBSTATE, 
          FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
          FLG_MEMIMPLICIT,
          FLG_BRANCHSTATE, 
@@ -1033,7 +1048,8 @@ context_setMode (cstring s)
          FLG_MODGLOBS, FLG_WARNLINTCOMMENTS,
          FLG_IFEMPTY, FLG_REALCOMPARE,
          FLG_BOOLOPS, FLG_PTRNEGATE,
-         FLG_SHIFTSIGNED,
+         FLG_SHIFTNEGATIVE,      
+         FLG_SHIFTIMPLEMENTATION,
          FLG_BUFFEROVERFLOWHIGH,
          FLG_BUFFEROVERFLOW,
          INVALID_FLAG 
@@ -1055,6 +1071,7 @@ context_setMode (cstring s)
           FLG_CHECKSTRICTGLOBALS, FLG_MACROMATCHNAME,
          FLG_RETVALOTHER,
          FLG_IFEMPTY, 
+         FLG_BUFFEROVERFLOWHIGH,
          FLG_RETSTACK, FLG_PTRNEGATE,
          FLG_STATETRANSFER, FLG_STATEMERGE,
          FLG_LONGUNSIGNEDINTEGRAL,
@@ -1079,9 +1096,11 @@ context_setMode (cstring s)
          FLG_CHECKMODGLOBALIAS,
          FLG_UNCHECKEDGLOBALIAS,
          FLG_FORMATCONST,
+         FLG_STRINGLITNOROOM,
+         FLG_STRINGLITSMALLER,
           FLG_EXITARG, FLG_PTRNUMCOMPARE, 
-         FLG_BOOLCOMPARE, FLG_MACROUNDEF
-         FLG_MUSTMOD, FLG_ALLGLOBALS,
+         FLG_BOOLCOMPARE, FLG_UNSIGNEDCOMPARE
+         FLG_MACROUNDEF, FLG_MUSTMOD, FLG_ALLGLOBALS,
          FLG_PREDBOOLOTHERS, FLG_PREDBOOLPTR, FLG_PREDBOOLINT,
          FLG_USEALLGLOBS, FLG_MUTREP, FLG_RETALIAS, 
          FLG_RETEXPOSE, FLG_ASSIGNEXPOSE, FLG_CASTEXPOSE,
@@ -1107,9 +1126,12 @@ context_setMode (cstring s)
          FLG_UNREACHABLE, 
          FLG_NORETURN, FLG_CASEBREAK, FLG_MISSCASE,
          FLG_EVALORDER, FLG_USEDEF, 
-
          FLG_NESTEDEXTERN, 
 
+         /* warn use flags */
+         FLG_MULTITHREADED, FLG_PORTABILITY, FLG_SUPERUSER, FLG_IMPLEMENTATIONOPTIONAL,
+         FLG_BUFFEROVERFLOWHIGH,
+
          /* memchecks flags */
 
          FLG_NULLSTATE, FLG_NULLDEREF, FLG_NULLASSIGN,
@@ -1137,7 +1159,9 @@ context_setMode (cstring s)
          FLG_IMMEDIATETRANS,
          FLG_ONLYUNQGLOBALTRANS,
          FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
-         FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE, 
+         FLG_MUSTFREEONLY,
+         FLG_MUSTFREEFRESH,
+         FLG_MUSTDEFINE, FLG_GLOBSTATE, 
          FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
          FLG_MEMIMPLICIT,
          FLG_BRANCHSTATE, 
@@ -1149,7 +1173,8 @@ context_setMode (cstring s)
           FLG_MACROMATCHNAME, FLG_WARNLINTCOMMENTS,
          FLG_INCLUDENEST, FLG_ANSIRESERVED, FLG_CPPNAMES, 
          FLG_NOPARAMS, FLG_IFEMPTY, FLG_WHILEEMPTY, FLG_REALCOMPARE,
-         FLG_BOOLOPS, FLG_SHIFTSIGNED,
+         FLG_BOOLOPS, FLG_SHIFTNEGATIVE,
+         FLG_SHIFTIMPLEMENTATION,
          FLG_BUFFEROVERFLOWHIGH, FLG_BUFFEROVERFLOW,
          INVALID_FLAG } ;
 
@@ -1166,6 +1191,8 @@ context_setMode (cstring s)
          FLG_MODFILESYSTEM,
          FLG_MACROMATCHNAME,
          FLG_FORMATCONST,
+         FLG_STRINGLITNOROOM,
+         FLG_STRINGLITSMALLER,
          FLG_STATETRANSFER, FLG_STATEMERGE,
           FLG_MACROUNDEF, FLG_MUTREP, FLG_MUSTMOD,
          FLG_ALLGLOBALS, FLG_IMPTYPE,
@@ -1190,8 +1217,8 @@ context_setMode (cstring s)
          FLG_VARUNUSED, 
          FLG_NULLPOINTERARITH, FLG_POINTERARITH, 
          FLG_PTRNUMCOMPARE, 
-         FLG_BOOLCOMPARE, FLG_NOEFFECT, 
-         FLG_RETVALINT, FLG_RETVALBOOL, FLG_RETVALOTHER, 
+         FLG_BOOLCOMPARE, FLG_UNSIGNEDCOMPARE,
+         FLG_NOEFFECT, FLG_RETVALINT, FLG_RETVALBOOL, FLG_RETVALOTHER, 
          FLG_ANSIRESERVED, FLG_ANSIRESERVEDLOCAL, FLG_CPPNAMES,
          FLG_RETVALBOOL, FLG_RETVALINT, FLG_SPECUNDEF, 
          FLG_DECLUNDEF, FLG_STRICTOPS, FLG_INCONDEFS, 
@@ -1213,6 +1240,11 @@ context_setMode (cstring s)
          FLG_NESTEDEXTERN, 
          FLG_FIRSTCASE,
 
+         /* warn use flags */
+         FLG_MULTITHREADED, FLG_PORTABILITY, FLG_SUPERUSER, FLG_IMPLEMENTATIONOPTIONAL,
+         FLG_BUFFEROVERFLOWHIGH,
+         FLG_BUFFEROVERFLOW, FLG_TOCTOU,
+
          /* memchecks flags */
          FLG_NULLSTATE, FLG_NULLDEREF, FLG_NULLASSIGN,
          FLG_NULLPASS, FLG_NULLRET,
@@ -1239,7 +1271,9 @@ context_setMode (cstring s)
          FLG_UNKNOWNINITTRANS,
 
          FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
-         FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE, 
+         FLG_MUSTFREEONLY,
+         FLG_MUSTFREEFRESH,
+         FLG_MUSTDEFINE, FLG_GLOBSTATE, 
          FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
          FLG_MEMIMPLICIT,
          FLG_BRANCHSTATE, 
@@ -1268,7 +1302,9 @@ context_setMode (cstring s)
          FLG_REALCOMPARE, FLG_BOOLOPS,
          FLG_SYSTEMDIRERRORS, FLG_UNUSEDSPECIAL,
 
-         FLG_SHIFTSIGNED, FLG_BITWISEOPS,
+         FLG_SHIFTNEGATIVE,
+         FLG_SHIFTIMPLEMENTATION,
+         FLG_BITWISEOPS,
          FLG_BUFFEROVERFLOWHIGH, FLG_BUFFEROVERFLOW,
          INVALID_FLAG
        } ;
@@ -1294,44 +1330,44 @@ context_isSpecialFile (cstring fname)
 bool
 context_isSystemDir (cstring dir)
 {
-  cstring sysDirs = context_exposeString (FLG_SYSTEMDIRS);
-  char *thisdir = cstring_toCharsSafe (sysDirs);
-  char *nextdir = strchr (thisdir, PATH_SEPARATOR);
-
-  if (nextdir != NULL)
+  cstring thisdir = cstring_copy (context_getString (FLG_SYSTEMDIRS));
+  cstring savedir = thisdir;
+  cstring nextdir = cstring_afterChar (thisdir, PATH_SEPARATOR);
+  
+  if (cstring_isDefined (nextdir))
     {
-      *nextdir = '\0';
+      /*@access cstring@*/
+      *nextdir = '\0'; /* closes thisdir */
       nextdir += 1;
+      /*@noaccess cstring@*/
     }
 
-  while (thisdir != NULL)
+  /* 2001-09-09: added thisdir[0] != '\0' 
+  **   herbert: don't compare with an empty name! 
+  **   should return false for empty directory path
+  */
+
+  while (!cstring_isEmpty (thisdir))
     {
       DPRINTF (("Test: %s / %s", dir, thisdir));
 
-      if (cstring_equalCanonicalPrefix (dir, thisdir))
+      if (osd_equalCanonicalPrefix (dir, thisdir))
        {
-         if (nextdir != NULL)
-           {
-             *(nextdir - 1) = PATH_SEPARATOR;
-           }
-         
+         cstring_free (savedir);
          return TRUE;
        }
 
-      if (nextdir != NULL)
-       {
-         *(nextdir - 1) = PATH_SEPARATOR;
-       }
-
-      if (nextdir != NULL)
+      if (cstring_isDefined (nextdir))
        {
          thisdir = nextdir;
-         nextdir = strchr (thisdir, PATH_SEPARATOR);
+         nextdir = cstring_afterChar (thisdir, PATH_SEPARATOR);
          
-         if (nextdir != NULL)
+         if (cstring_isDefined (nextdir))
            {
+             /*@access cstring@*/
              *nextdir = '\0';
              nextdir += 1;
+             /*@noaccess cstring@*/
            } 
        }
       else
@@ -1341,6 +1377,7 @@ context_isSystemDir (cstring dir)
     } 
 
   DPRINTF (("Returns FALSE"));
+  cstring_free (savedir);
   return FALSE;
 }
 
@@ -1377,6 +1414,11 @@ context_removeFileAccessType (typeId t)
 
 void context_enterFunctionHeader (void)
 {
+  if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("Enter function header: %q", context_unparse ()));
+    }
+
   if (gc.kind != CX_GLOBAL)
     {
       llparseerror (cstring_makeLiteral
@@ -1392,6 +1434,11 @@ void context_enterFunctionHeader (void)
 
 void context_exitFunctionHeader (void)
 {
+  if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("Exit function header: %q", context_unparse ()));
+    }
+
   DPRINTF (("Exit function header!"));
   gc.inFunctionHeader = FALSE;
 }
@@ -1403,21 +1450,38 @@ bool context_inFunctionHeader (void)
 
 void context_enterFunctionDeclaration (uentry e)
 {
+  if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("Enter function declaration: %q", context_unparse ()));
+    }
+
   DPRINTF (("Enter function decl"));
   llassert (gc.savekind == CX_ERROR);
   gc.savekind = gc.kind;
+  gc.savecont = gc.cont;
   gc.kind = CX_FCNDECLARATION;
   gc.cont.fcn = e;
 }
 
 void context_exitFunctionDeclaration (void)
 {
+  if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("Exit function declaration: %q", context_unparse ()));
+    }
+
   DPRINTF (("Exit function decl"));
   llassert (gc.savekind != CX_ERROR);
   llassert (gc.kind == CX_FCNDECLARATION);
   gc.kind = gc.savekind;
-  gc.cont.fcn = uentry_undefined;
+  gc.cont = gc.savecont;
+
   gc.savekind = CX_ERROR;
+
+  if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("After exit function declaration: %q", context_unparse ()));
+    }
 }
 
 bool context_inFunctionDeclaration (void)
@@ -1759,6 +1823,61 @@ context_enterFunction (/*@exposed@*/ uentry e)
   sRef_enterFunctionScope ();
 }
 
+void
+context_enterOldStyleScope (void)
+{
+  gc.kind = CX_OLDSTYLESCOPE;
+  DPRINTF (("Enter old style scope!"));
+  usymtab_enterFunctionScope (uentry_undefined);
+}
+
+void 
+context_completeOldStyleFunction (uentry e)
+{
+  llassert (gc.kind == CX_OLDSTYLESCOPE);
+
+  gc.kind = CX_FUNCTION;
+  gc.cont.fcn = e;
+  
+  DPRINTF (("Enter function: %s", uentry_unparse (e)));
+  
+  if (uentry_hasAccessType (e))
+    {
+      gc.acct = typeIdSet_subtract (typeIdSet_union (gc.facct, uentry_accessType (e)), 
+                                   gc.nacct);
+    }
+  else
+    {
+      gc.acct = gc.facct;
+    }
+  
+  DPRINTF (("Enter function: %s / %s", uentry_unparse (e), 
+           typeIdSet_unparse (gc.acct)));
+  
+  gc.showfunction = context_getFlag (FLG_SHOWFUNC);
+  
+  if (!globSet_isEmpty (uentry_getGlobs (e))) 
+    {
+      llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
+                            fileloc_unparse (g_currentloc), uentry_unparse (e)));
+    }
+
+  gc.showfunction = context_getFlag (FLG_SHOWFUNC);
+  
+  gc.globs = uentry_getGlobs (e);
+  globSet_clear (gc.globs_used);
+
+  gc.mods = uentry_getMods (e);
+
+  if (!sRefSet_isEmpty (gc.mods))
+    {
+      llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
+                            fileloc_unparse (g_currentloc), uentry_unparse (e)));
+    }
+
+  sRef_enterFunctionScope ();
+}
+
 static bool context_checkStrictGlobals (void)
 {
   return (context_getFlag (FLG_CHECKSTRICTGLOBALS));
@@ -2141,7 +2260,7 @@ void context_exitIterClause (exprNode body)
 
   context_setJustPopped ();
 
-  if (context_getFlag (FLG_LOOPEXEC))
+  if (context_getFlag (FLG_ITERLOOPEXEC))
     {
       usymtab_popTrueExecBranch (exprNode_undefined, body, ITERCLAUSE);
     }
@@ -2198,7 +2317,7 @@ void context_exitWhileClause (exprNode pred, exprNode body)
   ** predicate must be false after while loop (unless there are breaks)
   */
 
-  if (context_getFlag (FLG_LOOPEXEC))
+  if (context_getFlag (FLG_WHILELOOPEXEC))
     {
       usymtab_popTrueExecBranch (pred, body, WHILECLAUSE);
     }
@@ -2244,17 +2363,30 @@ void context_exitForClause (exprNode forPred, exprNode body)
   llassert (gc.inclause == FORCLAUSE);
   context_setJustPopped ();
 
+  DPRINTF (("Exit for: %s / %s", exprNode_unparse (forPred), exprNode_unparse (body)));
+
   /*
-  ** predicate must be false after while loop (unless there are breaks)
+  ** Predicate must be false after for loop (unless there are breaks)
   */
 
-  if (context_getFlag (FLG_LOOPEXEC))
+  if (context_getFlag (FLG_FORLOOPEXEC))
     {
+      DPRINTF (("Here: for loop exec"));
       usymtab_popTrueExecBranch (forPred, body, FORCLAUSE);
     }
   else
     {
-      usymtab_popTrueBranch (forPred, body, FORCLAUSE);
+      if (context_getFlag (FLG_OBVIOUSLOOPEXEC)
+         && exprNode_loopMustExec (forPred))
+       {
+         DPRINTF (("Here: loop must exec"));
+         usymtab_popTrueExecBranch (forPred, body, FORCLAUSE);
+       }
+      else
+       {
+         DPRINTF (("Pop true branch:"));
+         usymtab_popTrueBranch (forPred, body, FORCLAUSE);
+       }
     }
 
   usymtab_addGuards (invGuards);
@@ -2305,13 +2437,17 @@ context_returnFunction (void)
 void
 context_exitFunction (void)
 {    
+  DPRINTF (("Exit function: %s", context_unparse ()));
+
   if (!context_inFunction () && !context_inMacroConstant () 
-      && !context_inMacroUnknown () 
+      && !context_inUnknownMacro () 
       && !context_inIterDef () && !context_inIterEnd ())
     {
       /*
       ** not a bug because of parse errors
       */
+
+      BADBRANCH;
     }
   else
     {
@@ -2356,6 +2492,7 @@ context_exitFunction (void)
 
   llassert (clauseStack_isEmpty (gc.clauses));
   llassert (gc.inclause == NOCLAUSE);
+  DPRINTF (("After exit function: %s", context_unparse ()));
 }
 
 void
@@ -2366,7 +2503,7 @@ context_quietExitFunction (void)
       context_exitInnerPlain ();
     }
 
-  if (!context_inFunction () && !context_inMacroConstant () && !context_inMacroUnknown () 
+  if (!context_inFunction () && !context_inMacroConstant () && !context_inUnknownMacro () 
       && !context_inIterDef () && !context_inIterEnd ())
     {
     }
@@ -2617,10 +2754,9 @@ context_setValue (flagcode flag, int val)
     case FLG_INDENTSPACES:
       if (val < 0)
        {
-         
          llerror_flagWarning (message ("Value for %s must be a non-negative "
-                                   "number (given %d)",
-                                   flagcode_unparse (flag), val));
+                                       "number (given %d)",
+                                       flagcode_unparse (flag), val));
          return;
        }
 
@@ -2745,7 +2881,7 @@ context_setString (flagcode flag, cstring val)
     }
 
   if (cstring_length (val) >= 1
-      && cstring_firstChar (val) == '"')
+      && cstring_firstChar (val) == '\"')
     {
       llerror_flagWarning (message
                       ("setting %s to string beginning with \".  You probably "
@@ -2786,7 +2922,10 @@ void context_initMod (void)
    /*@globals undef gc; @*/
 {
   gc.kind = CX_GLOBAL;
+
   gc.savekind = CX_ERROR;
+  gc.savecont.glob = FALSE;
+
   gc.instandardlib = FALSE;
   gc.numerrors = 0;
   gc.neednl = FALSE;
@@ -2917,7 +3056,9 @@ context_unparse (void)
       s = message ("Global Context:%q", fileloc_unparse (g_currentloc));
       break;
     case CX_INNER:
-      s = message ("Inner Context:%q", fileloc_unparse (g_currentloc));
+      s = message ("Inner Context [%d] : %q", 
+                  gc.cont.cdepth,
+                  fileloc_unparse (g_currentloc));
       break;
     case CX_FUNCTION:
       s = message ("Function %q :%q \n\taccess %q\n\tmodifies %q",
@@ -2941,6 +3082,9 @@ context_unparse (void)
     case CX_ITEREND:
       s = message ("Iter end %q", uentry_unparse (gc.cont.fcn));
       break;
+    case CX_FCNDECLARATION:
+      s = message ("Function declaration %q", uentry_unparse (gc.cont.fcn));
+      break;
     default:
       s = message ("Un-unparseable context: %d", (int) gc.kind);
       break;
@@ -2973,6 +3117,11 @@ context_currentFunctionType (void)
 void
 context_enterInnerContext (void)
 {
+  if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("Enter inner context: %q", context_unparse ()));
+    }
+
   if (gc.kind == CX_GLOBAL)
     {
       gc.kind = CX_INNER;
@@ -2987,7 +3136,6 @@ context_enterInnerContext (void)
       ;
     }
 
-  
   usymtab_enterScope ();
   pushClause (NOCLAUSE);
 }
@@ -3001,7 +3149,11 @@ context_exitInnerPlain (void) /*@modifies gc;@*/
 void
 context_exitInner (exprNode exp)
 {
-  
+   if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("Enter inner context: %q", context_unparse ()));
+    }
   llassertprint (gc.inclause == NOCLAUSE || gc.inclause == CASECLAUSE,
                 ("inclause = %s", clause_nameTaken (gc.inclause)));
 
@@ -3032,6 +3184,11 @@ context_exitInner (exprNode exp)
 void
 context_enterStructInnerContext (void)
 {
+  if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("Enter struct inner context: %q", context_unparse ()));
+    }
+
   if (gc.kind == CX_GLOBAL)
     {
       gc.kind = CX_INNER;
@@ -3047,18 +3204,39 @@ context_enterStructInnerContext (void)
     }
 
   usymtab_enterScope ();
+
+  if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("Enter struct inner context: %q", context_unparse ()));
+    }
 }
 
 void
 context_exitStructInnerContext (void)
 {
+  if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("Exit struct inner context: %q [%d]", context_unparse (), gc.cont.cdepth));
+    }
+
   if (gc.kind == CX_INNER)
     {
-      if (--gc.cont.cdepth == 0)
+      if (gc.cont.cdepth <= 0)
        {
+         llcontbuglit ("Attempt to exit inner context with no depth");
          gc.kind = CX_GLOBAL;
          gc.cont.glob = TRUE;
+         gc.cont.cdepth = 0;
        }
+      else {
+       gc.cont.cdepth--;
+
+       if (gc.cont.cdepth == 0)
+         {
+           gc.kind = CX_GLOBAL;
+           gc.cont.glob = TRUE;
+         }
+      }
     }
   else 
     {
@@ -3070,17 +3248,26 @@ context_exitStructInnerContext (void)
     }
 
   usymtab_exitScope (exprNode_undefined);
+
+  if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("After exit struct inner context: %q [%d]", context_unparse (), gc.cont.cdepth));
+    }
 }
 
 void
 context_exitInnerSafe (void)
 {
-  
+  if (context_getFlag (FLG_GRAMMAR))
+    {
+      lldiagmsg (message ("Exit inner safe: %q", context_unparse ()));
+    }
+
   if (gc.kind == CX_INNER)
     {
-      if (--gc.cont.cdepth == 0)
+      if (--gc.cont.cdepth <= 0)
        {
-         gc.cont.cdepth++;
+         gc.cont.cdepth = 0;
        }
     }
   else if (gc.kind == CX_GLOBAL)
@@ -3534,10 +3721,10 @@ context_setFlagTemp (flagcode f, bool b)
         gc.flags[ff] = b; } while (FALSE)
 
 static void
-  context_setFlagAux (flagcode f, bool b, bool 
-                     inFile, /*@unused@*/ bool isRestore)
+context_setFlagAux (flagcode f, bool b, bool inFile, 
+                   /*@unused@*/ bool isRestore)
 {
-  DPRINTF (("set flag: %s / %s", flagcode_unparse (f), bool_unparse (b)));
+  DPRINTF (("Set flag: %s / %s", flagcode_unparse (f), bool_unparse (b)));
 
   if (f == FLG_USESTDERR) 
     {
@@ -3668,8 +3855,27 @@ static void
       DOSET (FLG_SPECRETIMPONLY, b);
       DOSET (FLG_SPECSTRUCTIMPONLY, b);
       break;
-    case FLG_ANSILIMITS: 
-      DOSET (FLG_ANSILIMITS, b);
+    case FLG_ANSI89LIMITS: 
+      DOSET (FLG_ANSI89LIMITS, b);
+      DOSET (FLG_CONTROLNESTDEPTH, b);
+      DOSET (FLG_STRINGLITERALLEN, b);
+      DOSET (FLG_INCLUDENEST, b);
+      DOSET (FLG_NUMSTRUCTFIELDS, b);
+      DOSET (FLG_NUMENUMMEMBERS, b);
+      
+      if (b)
+       {
+         context_setValue (FLG_CONTROLNESTDEPTH, ANSI89_CONTROLNESTDEPTH);
+         context_setValue (FLG_STRINGLITERALLEN, ANSI89_STRINGLITERALLEN);
+         context_setValue (FLG_INCLUDENEST, ANSI89_INCLUDENEST);
+         context_setValue (FLG_NUMSTRUCTFIELDS, ANSI89_NUMSTRUCTFIELDS);
+         context_setValue (FLG_NUMENUMMEMBERS, ANSI89_NUMENUMMEMBERS);
+         context_setValue (FLG_EXTERNALNAMELEN, ANSI89_EXTERNALNAMELEN);
+         context_setValue (FLG_INTERNALNAMELEN, ANSI89_INTERNALNAMELEN);
+       }
+      break;
+    case FLG_ISO99LIMITS: 
+      DOSET (FLG_ISO99LIMITS, b);
       DOSET (FLG_CONTROLNESTDEPTH, b);
       DOSET (FLG_STRINGLITERALLEN, b);
       DOSET (FLG_INCLUDENEST, b);
@@ -3678,11 +3884,13 @@ static void
       
       if (b)
        {
-         context_setValue (FLG_CONTROLNESTDEPTH, DEFAULT_CONTROLNESTDEPTH);
-         context_setValue (FLG_STRINGLITERALLEN, DEFAULT_STRINGLITERALLEN);
-         context_setValue (FLG_INCLUDENEST, DEFAULT_INCLUDENEST);
-         context_setValue (FLG_NUMSTRUCTFIELDS, DEFAULT_NUMSTRUCTFIELDS);
-         context_setValue (FLG_NUMENUMMEMBERS, DEFAULT_NUMENUMMEMBERS);
+         context_setValue (FLG_CONTROLNESTDEPTH, ISO99_CONTROLNESTDEPTH);
+         context_setValue (FLG_STRINGLITERALLEN, ISO99_STRINGLITERALLEN);
+         context_setValue (FLG_INCLUDENEST, ISO99_INCLUDENEST);
+         context_setValue (FLG_NUMSTRUCTFIELDS, ISO99_NUMSTRUCTFIELDS);
+         context_setValue (FLG_NUMENUMMEMBERS, ISO99_NUMENUMMEMBERS);
+         context_setValue (FLG_EXTERNALNAMELEN, ISO99_EXTERNALNAMELEN);
+         context_setValue (FLG_INTERNALNAMELEN, ISO99_INTERNALNAMELEN);
        }
       break;
     case FLG_EXTERNALNAMELEN:
@@ -3760,6 +3968,11 @@ static void
       DOSET (FLG_LOOPLOOPCONTINUE, b);
       DOSET (FLG_DEEPBREAK, b);
       break;
+    case FLG_LOOPEXEC:
+      DOSET (FLG_FORLOOPEXEC, b);
+      DOSET (FLG_WHILELOOPEXEC, b);
+      DOSET (FLG_ITERLOOPEXEC, b);
+      break;
     case FLG_ACCESSALL:
       DOSET (FLG_ACCESSMODULE, b);
       DOSET (FLG_ACCESSFILE, b);
@@ -3798,6 +4011,10 @@ static void
       DOSET (FLG_NULLPASS, b);
       DOSET (FLG_NULLRET, b);
       break;
+    case FLG_MUSTFREE:
+      DOSET (FLG_MUSTFREEONLY, b);
+      DOSET (FLG_MUSTFREEFRESH, b);
+      break;
     case FLG_MEMCHECKS:
       DOSET (FLG_NULLSTATE, b);
       DOSET (FLG_NULLDEREF, b);
@@ -3811,7 +4028,8 @@ static void
       DOSET (FLG_USERELEASED, b);
       DOSET (FLG_ALIASUNIQUE, b);
       DOSET (FLG_MAYALIASUNIQUE, b);
-      DOSET (FLG_MUSTFREE, b);
+      DOSET (FLG_MUSTFREEONLY, b);
+      DOSET (FLG_MUSTFREEFRESH, b);
       DOSET (FLG_MUSTDEFINE, b);
       DOSET (FLG_GLOBSTATE, b); 
       DOSET (FLG_COMPDESTROY, b);
@@ -3935,14 +4153,14 @@ void context_setFilename (fileId fid, int lineno)
 
 void context_enterIterDef (/*@observer@*/ uentry le)
 {
-    context_enterMacro (le);
+  context_enterMacro (le);
   gc.acct = typeIdSet_subtract (gc.facct, gc.nacct);
   gc.kind = CX_ITERDEF;
 }
 
 void context_enterIterEnd (/*@observer@*/ uentry le)
 {
-    context_enterMacro (le);
+  context_enterMacro (le);
   gc.kind = CX_ITEREND;
 }
 
@@ -4154,7 +4372,7 @@ bool context_inMacroConstant (void)
   return (gc.kind == CX_MACROCONST);
 }
 
-bool context_inMacroUnknown (void)
+bool context_inUnknownMacro (void)
 {   
   return (gc.kind == CX_UNKNOWNMACRO);
 }
@@ -4250,6 +4468,37 @@ bool context_inGlobalContext (void)
   return (gc.kind == CX_GLOBAL);
 }
 
+static void context_quietExitScopes (void)
+{
+  /*
+  ** Try to restore the global scope (after an error).
+  */
+
+  while (!usymtab_inFileScope ())
+    {
+      usymtab_quietExitScope (g_currentloc);
+    }
+
+  gc.cont.glob = TRUE;
+  gc.kind = CX_GLOBAL;
+}
+
+void context_checkGlobalScope (void)
+{
+  if (gc.kind != CX_GLOBAL)
+    {
+      if (context_inMacro ())
+       {
+         ; /* evans 2001-10-14: Okay to be in a macro here! */ 
+       }
+      else
+       {
+         llcontbug (message ("Not in global scope as expected: %q", context_unparse ()));
+         context_quietExitScopes ();
+       }
+    }
+}
+
 void context_setFileId (fileId s)
 {
   g_currentloc = fileloc_updateFileId (g_currentloc, s); 
This page took 0.068442 seconds and 4 git commands to generate.