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])
llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
}
- return defn;
+ /*@i1@*/ return defn; /* Spurious warning here */
}
/*
defn->pattern = NULL;
defn->nargs = nargs;
defn->predefined = NULL;
-
exp_p = defn->expansion = (char *) defn + sizeof (*defn);
defn->line = 0;
llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
}
- return defn;
+ /*@i1@*/ return defn; /* Spurious warning here */
}
/*
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;
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),
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;
}
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);
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
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)))
{
/*@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);
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));
{
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));
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 \
-$(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:
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 \
-$(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
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
--- /dev/null
+#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);
+}
--- /dev/null
+
+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