From: evans1629 Date: Tue, 16 Sep 2003 02:59:19 +0000 (+0000) Subject: Fixed processing of multi-dimensional arrays. X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/commitdiff_plain/f9e62f4012096f7ef8d1430541276b2bec85a69d Fixed processing of multi-dimensional arrays. --- diff --git a/configure.ac b/configure.ac index 80d85d2..efc3c60 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/src/cpplib.c b/src/cpplib.c index db2265e..66be54b 100644 --- a/src/cpplib.c +++ b/src/cpplib.c @@ -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; diff --git a/src/ctbase.i b/src/ctbase.i index c59eb76..c256432 100644 --- a/src/ctbase.i +++ b/src/ctbase.i @@ -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), diff --git a/src/ctype.c b/src/ctype.c index 8253a71..a03d657 100644 --- a/src/ctype.c +++ b/src/ctype.c @@ -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 diff --git a/src/uentry.c b/src/uentry.c index 1d9243f..5619532 100644 --- a/src/uentry.c +++ b/src/uentry.c @@ -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)); diff --git a/test/Makefile.am b/test/Makefile.am index 5c25a8c..3e49407 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -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: diff --git a/test/Makefile.in b/test/Makefile.in index f06bd53..db8c078 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -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 diff --git a/test/arrayinit.expect b/test/arrayinit.expect index cdc2b08..7d4bb3c 100644 --- a/test/arrayinit.expect +++ b/test/arrayinit.expect @@ -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 index 0000000..f05b40a --- /dev/null +++ b/test/innerarray.c @@ -0,0 +1,34 @@ +#include +#include + +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 index 0000000..cff7eb3 --- /dev/null +++ b/test/innerarray.expect @@ -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