]> andersk Git - splint.git/commitdiff
Fixed processing of multi-dimensional arrays.
authorevans1629 <evans1629>
Tue, 16 Sep 2003 02:59:19 +0000 (02:59 +0000)
committerevans1629 <evans1629>
Tue, 16 Sep 2003 02:59:19 +0000 (02:59 +0000)
configure.ac
src/cpplib.c
src/ctbase.i
src/ctype.c
src/uentry.c
test/Makefile.am
test/Makefile.in
test/arrayinit.expect
test/innerarray.c [new file with mode: 0644]
test/innerarray.expect [new file with mode: 0644]

index 80d85d28074eca34c645fe309ffc5b3c924124a3..efc3c6008014b3f990730952e3b23f8923a0a48d 100644 (file)
@@ -1,7 +1,7 @@
 dnl Process with autoconf to create a configure script  -*- Autoconf -*-
 AC_PREREQ(2.50)
 
-AC_INIT([Splint], [3.1.1.1], [splint-bug@splint.org], [splint])
+AC_INIT([Splint], [3.1.1.2], [splint-bug@splint.org], [splint])
 
 dnl This MUST precede any other macro
 AC_CONFIG_AUX_DIR([config])
index db2265e22c0e4fe1493a35d57561b865b27575d5..66be54b05e2375c74b22b5b4ff88b2b73c79659c 100644 (file)
@@ -1823,7 +1823,7 @@ collect_expansion (cppReader *pfile, char *buf, char *limit,
       llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
     }
 
-  return defn;
+  /*@i1@*/ return defn; /* Spurious warning here */
 }
 
 /*
@@ -1887,7 +1887,6 @@ collect_expansionLoc (fileloc loc, char *buf, char *limit,
   defn->pattern = NULL;
   defn->nargs = nargs;
   defn->predefined = NULL;
-
   exp_p = defn->expansion = (char *) defn + sizeof (*defn);
 
   defn->line = 0;
@@ -2170,7 +2169,7 @@ collect_expansionLoc (fileloc loc, char *buf, char *limit,
       llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
     }
 
-  return defn;
+  /*@i1@*/ return defn; /* Spurious warning here */
 }
 
 /*
@@ -6669,7 +6668,7 @@ get_next:
 
         case '\\':
          c2 = cppReader_peekC (pfile);
-         //! allow other stuff here if a flag is set?
+         /* allow other stuff here if a flag is set? */
          DPRINTF (("Got continuation!"));
          if (c2 != '\n')
            goto randomchar;
index c59eb7628313015a9b5de658abda9405dca3db3c..c256432cb7e972ab558318d7973a222ece092acb 100644 (file)
@@ -501,11 +501,67 @@ ctbase_unparse (ctbase c)
          return (message ("%t *", c->contents.base));
        }
     case CT_FIXEDARRAY:
-      return (message ("%t [%d]", 
-                      c->contents.farray->base, 
-                      (int) c->contents.farray->size));
+      /*
+      ** C prints out array declarations backwards, if
+      ** base is an array need to print out in reverse order.
+      */
+
+      if (ctype_isArray (c->contents.farray->base)) 
+       {
+         ctype base = c->contents.farray->base;
+         cstring res = message ("[%d]", (int) c->contents.farray->size);
+
+         while (ctype_isArray (base)) 
+           {
+             if (ctype_isFixedArray (base)) 
+               {
+                 res = message ("%q[%d]", 
+                                res, (int) ctype_getArraySize (base));
+               }
+             else
+               {
+                 res = message ("%q[]", res);
+               }
+
+             base = ctype_baseArrayPtr (base);
+           }
+
+         return (message ("%t %q", base, res));
+       } 
+      else 
+       {
+         return (message ("%t [%d]", 
+                          c->contents.farray->base, 
+                          (int) c->contents.farray->size));
+       }
     case CT_ARRAY:
-      return (message ("%t []", c->contents.base));
+      if (ctype_isArray (c->contents.base)) 
+       {
+         ctype base = c->contents.base;
+         cstring res = cstring_makeLiteral ("[]");
+
+         while (ctype_isArray (base)) 
+           {
+             if (ctype_isFixedArray (base)) 
+               {
+                 res = message ("%q[%d]", 
+                                res, (int) ctype_getArraySize (base));
+               }
+             else
+               {
+                 res = message ("%q[]", res);
+               }
+
+             base = ctype_baseArrayPtr (base);
+           }
+
+         return (message ("%t %q", base, res));
+
+       }
+      else
+       {
+         return (message ("%t []", c->contents.base));
+       }
     case CT_FCN:
       return (message ("[function (%q) returns %t]",
                       uentryList_unparseParams (c->contents.fcn->params),
index 8253a71322221fd2a311ca5efe8751eebc3a622d..a03d657e219e67f3668498586c2759eb9717afe5 100644 (file)
@@ -354,29 +354,50 @@ ctype ctype_makeFixedArray (ctype c, size_t size)
   return res;
 }
 
+/*
+** In C, array terms appear backwards:
+**
+**        int a[5][7]
+**
+** declares an array of 5 elements, each of which is
+** an array of 7 int's.
+**
+** We represent this as,
+**
+**        array (array (int, 7), 5)
+**
+** Hence, the rightmost declaration is the innermost type.
+*/
+
 ctype ctype_makeInnerFixedArray (ctype c, size_t size)
 {
   ctype res;
 
+  DPRINTF (("makeinnerfixed: %s / %d", ctype_unparse (c), size));
+
   if (ctype_isFixedArray (c))
     {
       ctype cb = ctype_baseArrayPtr (c);
       size_t osize = ctype_getArraySize (c);
       
       res = ctype_makeFixedArray (ctype_makeInnerFixedArray (cb, size), osize);
+      DPRINTF (("res 1: %s", ctype_unparse (res)));
     }
   else if (ctype_isArray (c))
     {
       ctype cb = ctype_baseArrayPtr (c);
 
       res = ctype_makeArray (ctype_makeInnerFixedArray (cb, size));
+      DPRINTF (("res 2: %s", ctype_unparse (res)));
     }
   else
     {
       res = ctype_makeFixedArray (c, size);
+      DPRINTF (("res 3: %s", ctype_unparse (res)));
     }
 
-  DPRINTF (("Make inner fixed array: %s", ctype_unparse (res)));
+  DPRINTF (("Make inner fixed array: %s / base: %s", 
+           ctype_unparse (res), ctype_unparse (ctype_baseArrayPtr (res))));
   return res;
 }
 
@@ -393,6 +414,11 @@ ctype ctype_makeInnerArray (ctype c)
       
       res = ctype_makeFixedArray (ctype_makeInnerArray (cb), osize);
     }
+  else if (ctype_isArray (c)) 
+    {
+      ctype cb = ctype_baseArrayPtr (c);
+      res = ctype_makeArray (ctype_makeInnerArray (cb));
+    }
   else
     {
       res = ctype_makeArray (c);
@@ -1833,7 +1859,19 @@ ctype_isArray (ctype c)
 
 bool ctype_isIncompleteArray (ctype c)
 {
-  return (ctype_isArray (c) && !ctype_isFixedArray (c));
+  if (ctype_isArray (c)) 
+    {
+      if (ctype_isFixedArray (c)) 
+       {
+         return ctype_isIncompleteArray (ctype_baseArrayPtr (c));
+       }
+      else 
+       {
+         return TRUE;
+       }
+    }
+
+  return FALSE;
 }
 
 bool
index 1d9243f663c10755f310c943b4b4d98bd36d8408..5619532741f35f1d53690593bed2979fd835738c 100644 (file)
@@ -753,6 +753,10 @@ void uentry_checkParams (uentry ue)
                  
                  if (ctype_isFixedArray (ct))
                    {
+                     DPRINTF (("Array: %s / %s",
+                               ctype_unparse (ct),
+                               ctype_unparse (ctype_baseArrayPtr (ct))));
+
                      if (ctype_isArray (ctype_baseArrayPtr (ct))
                          && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
                        {
@@ -3068,7 +3072,6 @@ uentry_isSpecialFunction (uentry ue)
 /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
 {
   ctype ct = idDecl_getCtype (t);
-  ctype base = ct;
   fileloc loc = setLocation ();
   sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc, SA_CREATED));
   uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
@@ -3078,26 +3081,22 @@ uentry_isSpecialFunction (uentry ue)
   uentry_reflectQualifiers (ue, idDecl_getQuals (t));
   uentry_implicitParamAnnots (ue);
 
-  /* Parameter type [][] or [x][] is invalid, but [][x] is okay */
-
-  while (ctype_isFixedArray (base)) 
-    {
-      base = ctype_baseArrayPtr (base);
-    }
-  
-  DPRINTF (("Base: %s", ctype_unparse (base)));
-  
-  if (ctype_isIncompleteArray (base)) 
+  if (ctype_isArray (ct)) 
     {
-      base = ctype_baseArrayPtr (base);
-      DPRINTF (("Base: %s", ctype_unparse (base)));
-      if (ctype_isArray (base))
+      /* Parameter type [][] or [x][] is invalid, but [][x] is okay */
+      ctype base = ctype_baseArrayPtr (ct);
+
+      DPRINTF (("Check array: %s / Base: %s", ctype_unparse (ct),
+               ctype_unparse (base)));
+      
+      if (ctype_isIncompleteArray (base)) 
        {
          if (!uentry_hasName (ue)) 
            {
              voptgenerror 
                (FLG_INCOMPLETETYPE, 
-                message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
+                message ("Unnamed function parameter %d is incomplete type "
+                         "(inner array must have bounds): %s",
                          i + 1,
                          ctype_unparse (ct)),
                 uentry_whereLast (ue));
@@ -3106,7 +3105,8 @@ uentry_isSpecialFunction (uentry ue)
            {
              voptgenerror 
                (FLG_INCOMPLETETYPE, 
-                message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
+                message ("Function parameter %q is incomplete type "
+                         "(inner array must have bounds): %s",
                          uentry_getName (ue),
                          ctype_unparse (ct)),
                 uentry_whereLast (ue));
index 5c25a8cfe1e0a14d9d0af5ee4952e5a10c618d08..3e49407681a69ca02e264cbbc99d15116de5bc15 100644 (file)
@@ -44,7 +44,7 @@ UNITTESTS = \
   args arraydims arrayinit arraylit blocks break cases cast chararraylit charlit clauses commentchar compdestroy \
   compoundliterals compoundstmt constannot controldepth csyntax czechnames czechoslovaknames deadparam \
   decl divzero enum enumtag exports external fields flags forbody format freearray \
-  funcpointer functionmacro glob globals impabstract info init inparam internal iter keep libs \
+  funcpointer functionmacro glob globals impabstract info init innerarray inparam internal iter keep libs \
   linked lintcomments list longint loopexec looptesteffect \
   macros macrosef malloc merge mergenull modifies modtest moduncon \
   mongoincludes mystrncat noeffect null nullret nullassign numabstract observer oldstyle outglob outparam \
@@ -471,6 +471,12 @@ init:
        -$(SPLINTR) init.c -expect 14
        -$(SPLINTRN) init.c +checks -exportlocal -exportheadervar -expect 17
 
+### evans 2003-09-16
+.PHONY: innerarray
+innerarray:
+       -$(SPLINTR) innerarray.c -expect 10
+
+
 
 .PHONY: inparam
 inparam:
index f06bd5326e8c51e087c100be50b7769c017b64dc..db8c078df5525af430715c74047841d1f60a66e3 100644 (file)
@@ -132,7 +132,7 @@ UNITTESTS = \
   args arraydims arrayinit arraylit blocks break cases cast chararraylit charlit clauses commentchar compdestroy \
   compoundliterals compoundstmt constannot controldepth csyntax czechnames czechoslovaknames deadparam \
   decl divzero enum enumtag exports external fields flags forbody format freearray \
-  funcpointer functionmacro glob globals impabstract info init inparam internal iter keep libs \
+  funcpointer functionmacro glob globals impabstract info init innerarray inparam internal iter keep libs \
   linked lintcomments list longint loopexec looptesteffect \
   macros macrosef malloc merge mergenull modifies modtest moduncon \
   mongoincludes mystrncat noeffect null nullret nullassign numabstract observer oldstyle outglob outparam \
@@ -1278,6 +1278,11 @@ init:
        -$(SPLINTR) init.c -expect 14
        -$(SPLINTRN) init.c +checks -exportlocal -exportheadervar -expect 17
 
+### evans 2003-09-16
+.PHONY: innerarray
+innerarray:
+       -$(SPLINTR) innerarray.c -expect 10
+
 .PHONY: inparam
 inparam:
        -$(SPLINTR) inparam.c -expect 2
index cdc2b08aea13b945389e8869e356849c7059f354..7d4bb3cc00bc82f00592028fb94052ed4dd9721a 100644 (file)
@@ -4,7 +4,7 @@ arrayinit.c:1:12: Initializer block for x has 4 elements, but declared as int
 arrayinit.c:2:12: Initializer block for a has 2 elements, but declared as int
                      [3]: 1, 2
 arrayinit.c:3:16: Initializer block for aa has 2 elements, but declared as int
-                     [3] [3]: { 1, 2, 3 }, { 4, 5 }
+                     [3][3]: { 1, 2, 3 }, { 4, 5 }
 arrayinit.c:4:18: Initializer block for aa[1] has 2 elements, but declared as
                      int [3]: 4, 5
 arrayinit.c:10:15: String literal with 4 characters is assigned to char [3] (no
diff --git a/test/innerarray.c b/test/innerarray.c
new file mode 100644 (file)
index 0000000..f05b40a
--- /dev/null
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int fn(int arr[/*7*/][10]) /* better without the 7 */
+{
+  return 0;
+}
+
+int fn2(int arr[10][]) /* bad */
+{
+  return 0;
+}
+
+int fn3(int arr[][]) /* bad */
+{
+  return 0;
+}
+
+int fn4(int arr[][10][7][4]) 
+{
+  return 0;
+}
+
+int fn5(int arr[][10][][4]) /* bad */
+{
+  return 0;
+}
+
+int main()
+{
+  int array[10][]; /* incomplete type bad */
+  int array2[][10]; /* array size missing */
+  return fn(array);
+}
diff --git a/test/innerarray.expect b/test/innerarray.expect
new file mode 100644 (file)
index 0000000..cff7eb3
--- /dev/null
@@ -0,0 +1,23 @@
+
+innerarray.c: (in function fn)
+innerarray.c:4:12: Parameter arr not used
+innerarray.c:9:13: Function parameter arr is incomplete type (inner array must
+                      have bounds): int [10][]
+innerarray.c: (in function fn2)
+innerarray.c:9:13: Parameter arr not used
+innerarray.c:14:13: Function parameter arr is incomplete type (inner array must
+                       have bounds): int [][]
+innerarray.c: (in function fn3)
+innerarray.c:14:13: Parameter arr not used
+innerarray.c: (in function fn4)
+innerarray.c:19:13: Parameter arr not used
+innerarray.c:24:13: Function parameter arr is incomplete type (inner array must
+                       have bounds): int [][10][][4]
+innerarray.c: (in function fn5)
+innerarray.c:24:13: Parameter arr not used
+innerarray.c: (in function main)
+innerarray.c:33:13: Passed storage array not completely defined (*array is
+                       undefined): fn (array)
+innerarray.c:32:7: Variable array2 declared but not used
+
+Finished checking --- 10 code warnings, as expected
This page took 0.071022 seconds and 5 git commands to generate.